题目描述
Koishi喜欢线段。
她的\(n\)条线段都能表示成数轴上的某个闭区间\([l,r]\)。Koishi喜欢在把所有线段都放在数轴上,然后数出某些点被多少线段覆盖了。
Flandre看她和线段玩得很起开心,就抛给她一个问题:
数轴上有\(m\)个点突然兴奋,如果自己被身上覆盖了超过\(x\)条线段,这个点就会浑身难受然后把Koishi批判一番。
Koishi十分善良,为了不让数轴上的点浑身难受,也为了让自己开心,她想在数轴上放入尽量多的线段。
按照套路,Koishi假装自己并不会做这道题,所以她就来求你帮忙。并承诺如果你解决了问题就给你打一通电话w。
输入格式
第一行两个个整数n,mn,mn,m,分别表示插入的线段数和关键点数。
接下来\(n\)行,每行两个整数\(l,r(l\leq r)\),表示线段\([l,r]\)的端点。
接下来\(m\)行,每行两个整数\(p,x\),表示有个位于ppp的点突然兴奋,并认为自己身上不得覆盖超过\(x\)条线段
输出格式
一个整数,表示最多能放入的线段数
#include<queue>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
const int N=8e5+5;
#define int long long
int b[N],num,n,m;
#define lb lower_bound
int e[N],P[N],X[N];
struct mzx{
int l,r;
}a[N];
inline bool nmp(mzx a,mzx b){
return a.l<b.l;
}
priority_queue<int>Q;
int vis[N];
signed main(){
cin>>n>>m;
for(int i=1,l,r;i<=n;i++){
scanf("%lld%lld",&l,&r);
b[++num]=l,b[++num]=r;
a[i]=(mzx){l,r};
}
for(int i=1;i<=m;i++){
scanf("%lld%lld",&P[i],&X[i]);
b[++num]=P[i];
}
sort(b+1,b+1+num);
int len=unique(b+1,b+1+num)-b-1;
for(int i=1;i<=n;i++){
a[i].l=lb(b+1,b+1+len,a[i].l)-b;
a[i].r=lb(b+1,b+1+len,a[i].r)-b;
}
sort(a+1,a+1+n,nmp);
for(int i=1;i<=len;i++)e[i]=2e9;
for(int i=1;i<=m;i++){
P[i]=lb(b+1,b+1+len,P[i])-b;
e[P[i]]=min(e[P[i]],X[i]);
}
int st=1,ans=0;
for(int i=1;i<=len;i++){
vis[i]+=vis[i-1];
while(a[st].l==i&&st<=n){
Q.push(a[st].r);
vis[i]++; vis[a[st].r+1]--;
st++; ans++;
}
int op=vis[i]-e[i];
if(op<=0)continue;
while(op--){
vis[Q.top()+1]--;
Q.pop();
vis[i]--;
ans--;
}
}
cout<<ans<<endl;
}