很基本的題目.
爲了練習OOP,本身寫個堆....
把全部區間按照左端點排個序,依次考慮左端點小於x的全部區間,在這些區間中找出最大的k個右端點,用堆維護就能夠了.
調了一下子.代碼能力真是差啊.spa
#include<cstdio> #include<algorithm> using namespace std; class interval{ public: int l,r,num; interval(){} interval(int _l,int _r){ l=_l;r=_r; } bool operator <(const interval &B)const{ return r<B.r; } }; class heap{ private: interval* v; int sz,MEMSZ; void expand(){ if(MEMSZ==0){ MEMSZ=100;sz=0; v=new interval[MEMSZ]; }else{ interval* P= new interval[MEMSZ*2]; for(int i=1;i<=sz;++i)P[i]=v[i]; delete[] v; v=P;MEMSZ=MEMSZ*2; } } public: heap(){ sz=0;MEMSZ=0; } int size(){ return sz; } void add(interval A){ if(sz+1>=MEMSZ)expand(); v[++sz]=A; int y=sz; while(y>1&&(v[y]<v[y>>1])){ swap(v[y],v[y>>1]);y>>=1; } } void pop(){ if(sz==1)sz=0; else{ swap(v[1],v[sz]);--sz; int y=1; while((y<<1)<=sz){ int p=(y<<1); if((p+1)<=sz&&v[p+1]<v[p])p=p+1; if(v[p]<v[y]){ swap(v[p],v[y]); y=p; } else break; } } } void clear(){ delete[] v; sz=MEMSZ=0; } int top(){ if(sz>=1)return v[1].r; else return -1; } void Enum(){ for(int i=1;i<=sz;++i)printf("%d%c",v[i].num,(i==sz)?'\n':' '); } ~heap(){ clear(); } }; interval P[1000006]; bool cmp(const interval &a,const interval &b){ return a.l<b.l; } int ans=0,n,k; void work(int flag){ heap a; for(int i=1;i<k;++i){ a.add(P[i]); } for(int i=k;i<=n;++i){ a.add(P[i]); while(a.size()>k){ a.pop(); } int R=a.top();//printf(":%d %d\n",P[i].l,R); if(R-P[i].l>ans){ ans=R-P[i].l;//printf("!%d\n",R-P[i].l); } if(flag&&R-P[i].l==ans){ a.Enum();return; } } } int main(){ scanf("%d%d",&n,&k); for(int i=1;i<=n;++i)scanf("%d%d",&P[i].l,&P[i].r),P[i].num=i; sort(P+1,P+n+1,cmp); work(0); printf("%d\n",ans); if(ans==0){ for(int i=1;i<=k;++i)printf("%d%c",i,(i==k)?'\n':' ');return 0; } work(1); return 0; }