bzoj 5102: [POI2018]Prawnicy

10 篇文章 0 订阅

题意:

定义一个区间(l,r)的长度为r-l,空区间的长度为0。
给定数轴上n个区间,请选择其中恰好k个区间,使得交集的长度最大。

题解:

一眼主席树(大sb)
其实线段树即可,按左端点排序,依次插入线段树,然后就可以在线段树上二分得到右端点。
然后传说会tle,将线段树换成堆即可,维护第k大的右端点。
卡时过。
code:

#include<queue>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
struct Node{
    int l,r,num;
}a[1000010];
int n,k;
bool cmp(Node a,Node b) {return a.l<b.l;}
struct node{
    int x,r;
    node() {}
    node(int a,int b) {x=a;r=b;}
};
bool operator < (node a,node b) {return a.r>b.r;}
priority_queue<node> q;
int main()
{
    scanf("%d %d",&n,&k);
    for(int i=1;i<=n;i++) scanf("%d %d",&a[i].l,&a[i].r),a[i].num=i;
    sort(a+1,a+n+1,cmp);
    int ans=0,num=0,x=-1;
    for(int i=1;i<=n;i++)
    {
        if(k==1)
        {
            int len=a[i].r-a[i].l;
            if(ans<len) x=a[i].num,ans=len;
        }
        else if(num==k-1)
        {
            int len=min(q.top().r,a[i].r)-a[i].l;
            if(ans<len) x=a[i].num,ans=len;
        }
        num++;q.push(node(a[i].num,a[i].r));
        if(num==k) num--,q.pop();
    }
    printf("%d\n",ans);
    while(!q.empty()) q.pop();num=0;
    for(int i=1;i<=n;i++)
    {
        if(a[i].num==x||(x==-1&&num==k-1))
        {
            while(!q.empty()) printf("%d ",q.top().x),q.pop();
            printf("%d",a[i].num);
            return 0;
        }
        num++;q.push(node(a[i].num,a[i].r)); 
        if(num==k) num--,q.pop();
    }
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值