#贪心,平衡树#洛谷 3602 Koishi Loves Segments

博客围绕有n个区间和m个限制的题目展开,限制为第i个点不得覆盖超过ti个区间。分析时先对限制排序,按贪心思想对区间开头排序,删掉无限制区间,不满足时删除末尾大的区间,使用平衡树(作者用multiset)求解,时间复杂度O(m+nlogn),最后给出代码。

题目

nnn个区间,有mmm个限制,第iii个点不得覆盖超过tit_iti个区间,问最多能保留多少个区间


分析

首先对于每个限制进行排序,那按照贪心的思想,首先对区间的开头进行排序,那首先之前没有限制的区间可以删掉了,然后如果不满足,区间的末尾越大,越值得删掉,因为这个区间很有可能继续受到影响,那就是平衡树了,但是我太菜了,只会multiset,时间复杂度O(m+nlogn)O(m+nlogn)O(m+nlogn)


代码

#include <cstdio>
#include <cctype>
#include <algorithm>
#include <set>
#define rr register
#define getchar() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<13,stdin)),p1==p2?EOF:*p1++)
using namespace std;
struct rec{int x,y;}a[200001],b[400001]; char buf[1<<13],*p1,*p2;
multiset<int>uk; int n,m,ans;
inline signed iut(){
    rr int ans=0,f=1; rr char c=getchar();
    while (!isdigit(c)) f=(c=='-')?-f:f,c=getchar();
    while (isdigit(c)) ans=(ans<<3)+(ans<<1)+(c^48),c=getchar();
    return ans*f;
}
bool cmp(rec a,rec b){return a.x<b.x;}
signed main(){
    ans=n=iut(),m=iut();
    for (rr int i=0;i<n;++i) a[i]=(rec){iut(),iut()};
    for (rr int i=0;i<m;++i) b[i]=(rec){iut(),iut()};
    sort(a,a+n,cmp),sort(b,b+m,cmp);
    for(rr int i=0,j=0;i<m;++i){
        while(j<n&&a[j].x<=b[i].x) uk.insert(a[j++].y);
        while(uk.size()&&*uk.begin()<b[i].x) uk.erase(uk.begin());
        while(uk.size()>b[i].y) uk.erase(--uk.end()),--ans;
    }
    return !printf("%d",ans);
}
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值