[堆] Jzoj P5861 失意

Description

 

Input

Output

 

Sample Input

4
6 3
3 8
4 12
2 6
1 10
5 9
11 12

Sample Output

4
1 2 4
 

Data Constraint

 

Hint

题解

  • 考虑对于一个交集,那么就是一条线段的右端点于一条线段的左端点的交集大小
  • 则ans=min(右端点坐标)-max(左端点坐标)
  • 考虑一种对于每个左端点统计答案的做法
  • 我们把线段按照左端点从小到大排序,依次选择
  • 每当选择一条线段,我们将它的右端点放进堆中
  • 当堆中已有 m 个元素时
  • 弹出最小的右端点减去当前左端点

代码

 1 #include <cstdio>
 2 #include <algorithm>
 3 #include <queue>
 4 #include <bitset>
 5 using namespace std;
 6 struct edge 
 7 {
 8     int l,r,d;
 9     bool operator <(edge b) const { return r>b.r; }
10 } e[1000005],head;
11 std:: priority_queue<edge>Q;
12 std:: bitset<1000005>visit,vis;
13 bool cmp(edge a,edge b) { return a.l==b.l?a.r<b.r:a.l<b.l; }
14 int num,n,m,tot,ans;
15 int main()
16 {
17     freopen("failure.in","r",stdin);
18     freopen("failure.out","w",stdout);
19     scanf("%d%d%d",&num,&n,&m);
20     for (int i=1;i<=n;i++) scanf("%d%d",&e[i].l,&e[i].r),e[i].d=i;
21     sort(e+1,e+n+1,cmp);
22     for (int i=1;i<=m;i++) Q.push(e[i]),++tot,visit[e[i].d]=1;
23     head=Q.top(),ans=max(head.r-e[m].l,0),vis=visit;
24     for (int i=m+1;i<=n;i++)
25     {
26         Q.push(e[i]),++tot,visit[e[i].d]=1;
27         if (tot>m) head=Q.top(),visit[head.d]=0,Q.pop(),tot--;
28         if (tot==m)
29         {
30             head=Q.top();
31             int mx=max(0,head.r-e[i].l);
32             if (mx>=ans) ans=mx,vis=visit;
33         }
34     }
35     printf("%d\n",ans);
36     for (int i=1;i<=n;i++) if (vis[i]) printf("%d ",i);
37 }

猜你喜欢

转载自www.cnblogs.com/Comfortable/p/9649794.html
今日推荐