rt,做法是用树状数组维护 1 到 x 中有多少个区间左端点,然后用二分找到当前区间后的第一个没有被占用的区间,然后再枚举给第国内多少个机场统计答案就好了。
小样例(包括自己造的)都过了,但是大样例没过。
#include<bits/stdc++.h>
using namespace std;
const int N=1e5+5;
int s[N<<2],n,ma,mb,c[N],sa[N],sb[N],m,p[N<<1],sum[N];
struct node{
int l,r;
}a[N];
int lowbit(int x){return x&(-x);}
void add(int x,int t){for(;t<=(m<<1);t+=lowbit(t))s[t]+=x;return ;}
int query(int t){int ans=0;for(;t>0;t-=lowbit(t))ans+=s[t];return ans;}
bool cmp(node a,node b){
return a.l<b.l;
}
void work() {
int cnt=0;
memset(c,0,sizeof(c));
for(int i=1;i<=m;++i){
cin>>a[i].l>>a[i].r;
c[++cnt]=a[i].l;
c[++cnt]=a[i].r;
}
sort(c+1,c+cnt+1);
for(int i=1;i<=m;++i){
a[i].l=lower_bound(c+1,c+cnt+1,a[i].l)-c;
p[a[i].l]=i;
add(1,a[i].l);
a[i].r=lower_bound(c+1,c+cnt+1,a[i].r)-c;
}
int t=0;
sort(a+1,a+m+1,cmp);
while(query(m<<1)){
t++;
int now=0;
while(query(m<<1)!=query(now)&&now<(m<<1)){
int l=now+1,r=m<<1,x=query(now)+1;
while(l<r){
int mid=l+r>>1;
if(query(mid)<x)
l=mid+1;
else r=mid;
}
sum[t]++;
// cout<<p[l]<<' '<<t<<endl;
add(-1,l);
now=a[p[l]].r;
}
}
for(int i=1;i<=m;++i)
a[i].l=a[i].r=0;
return ;
}
int main(){
ios::sync_with_stdio(0);
cin.tie(0),cout.tie(0);
cin>>n>>ma>>mb;
m=ma;
work();
for(int i=1;i<=n;++i)
sa[i]=sa[i-1]+sum[i];
// cout<<endl;
memset(sum,0,sizeof(sum));
m=mb;
work();
int ans=0;
for(int i=1;i<=m;++i)
sum[i]=sum[i-1]+sum[i];
// for(int i=1;i<=m;++i)
// cout<<sum[i]<<' ';
// cout<<endl;
for(int i=0;i<=n;++i)
ans=max(ans,sa[i]+sum[n-i]);
cout<<ans<<endl;
return 0;
}
/*4 5 2
1 15
3 13
5 11
7 9
10 12
8 14
6 164 4 3
1 15
3 13
5 11
7 9
10 12
8 14
6 16
*/