1. 程式人生 > >[POI2018]Prawnicy

[POI2018]Prawnicy

for 題目 UC AD con not gist urn put

題目大意:
  有$n(n\le10^6)$個線段,每個線段覆蓋的範圍是$[l_i,r_i]$,要求從中選取$k(k\le10^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\n",ans[0]); 67 for(register int i=1;i<=k;i++) { 68 printf("%d%c",ans[i]," \n"[i==k]); 69 } 70 return 0; 71 }

[POI2018]Prawnicy