BZOJ5102: [POI2018]Prawnicy

 1 //思路:贪心+堆 
 2 #include<iostream>
 3 #include<cstdio>
 4 #include<algorithm>
 5 #include<cstring>
 6 #include<queue>
 7 using namespace std;
 8 const int maxn=1000005;
 9 int n,k,ans,ans_l,ans_r;//ans--答案区间长度 ans_l--答案区间左端点 ans_r--答案区间右端点 
10 struct node{
11     int l,r,id;
12     inline bool operator < (const node &b)const{
13         return this->r>b.r;
14     }
15 }a[maxn];
16 inline bool cmp(const node &a,const node &b){
17     return a.l<b.l||(a.l==b.l&&a.r<b.r);
18 }
19 priority_queue<node> q;//堆 按右端点从小到大存放 
20 int main(){
21     scanf("%d%d",&n,&k);
22     for(int i=1;i<=n;++i) scanf("%d%d",&a[i].l,&a[i].r),a[i].id=i;
23     sort(a+1,a+1+n,cmp);//按左端点排序 
24     for(int i=1;i<=n;++i){//从小到大枚举每个左端点作为答案区间左端点 
25         q.push(a[i]);//利用堆寻找在当前左端点下k个可行右端点中最小(距离左端点最近)的那个 
26         while(!q.empty()&&q.size()>k) q.pop();
27         if(q.size()==k&&q.top().r-a[i].l>ans){
28             ans=q.top().r-a[i].l;
29             ans_l=a[i].l,ans_r=q.top().r;
30         }
31     }
32     printf("%d\n",ans);
33     for(int i=1;k&&i<=n;++i){
34         if(a[i].l<=ans_l&&a[i].r>=ans_r) printf("%d ",a[i].id),--k;//利用答案区间的左右端点查找包含答案区间 的区间 的编号 
35     }
36     return 0;
37 }

猜你喜欢

转载自www.cnblogs.com/yu-xing/p/10349333.html