题目大意:
有$n(nle10^6)$个线段,每个线段覆盖的范围是$[l_i,r_i]$,要求从中选取$k(kle10^6)$个线段使得这些线段覆盖范围的交集最大,求最大交集及任意一种方案。
思路:
对左端点排序,用堆维护右端点即可。
1 #include<queue> 2 #include<cstdio> 3 #include<cctype> 4 #include<algorithm> 5 #include<sys/mman.h> 6 #include<sys/stat.h> 7 class MMapInput { 8 private: 9 char *buf,*p; 10 int size; 11 public: 12 MMapInput() { 13 register int fd=fileno(stdin); 14 struct stat sb; 15 fstat(fd,&sb); 16 size=sb.st_size; 17 buf=reinterpret_cast<char*>(mmap(0,size,PROT_READ,MAP_PRIVATE,fileno(stdin),0)); 18 p=buf; 19 } 20 char getchar() { 21 return (p==buf+size||*p==EOF)?EOF:*p++; 22 } 23 }; 24 MMapInput mmi; 25 inline int getint() { 26 register char ch; 27 while(!isdigit(ch=mmi.getchar())); 28 register int x=ch^'0'; 29 while(isdigit(ch=mmi.getchar())) x=(((x<<2)+x)<<1)+(ch^'0'); 30 return x; 31 } 32 const int N=1e6+1; 33 int ans[N]; 34 struct Segment { 35 int l,r,id; 36 bool operator < (const Segment &another) const { 37 return l<another.l; 38 } 39 }; 40 Segment seg[N]; 41 std::priority_queue<int,std::vector<int>,std::greater<int> > q1; 42 std::priority_queue<std::pair<int,int>,std::vector<std::pair<int,int> >,std::greater<std::pair<int,int> > > q2; 43 int main() { 44 const int n=getint(),k=getint(); 45 for(register int i=1;i<=n;i++) { 46 const int l=getint(),r=getint(); 47 seg[i]=(Segment){l,r,i}; 48 } 49 std::sort(&seg[1],&seg[n]+1); 50 int pos; 51 for(register int i=1;i<=n;i++) { 52 while((int)q1.size()>=k) q1.pop(); 53 q1.push(seg[i].r); 54 if(i>=k&&q1.top()-seg[i].l>ans[0]) { 55 ans[0]=q1.top()-seg[pos=i].l; 56 } 57 } 58 for(register int i=1;i<=pos;i++) { 59 while((int)q2.size()>=k) q2.pop(); 60 q2.push(std::make_pair(seg[i].r,seg[i].id)); 61 } 62 for(register int i=1;i<=k;i++) { 63 ans[i]=q2.top().second; 64 q2.pop(); 65 } 66 printf("%d ",ans[0]); 67 for(register int i=1;i<=k;i++) { 68 printf("%d%c",ans[i]," "[i==k]); 69 } 70 return 0; 71 }