[POI2018]Prawnicy

题目大意:
  有$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 }
原文地址:https://www.cnblogs.com/skylee03/p/8722785.html