跟大部分人想法一致,只不過預處理貢獻時使用的二分+並查集而不是set。時間復雜度為 $ O(n \alpha(n) \log n ) $ ,多了個反阿克曼,但實際跑起來比set要快(set自帶大常數)。
代碼:
#include <bits/stdc++.h>
using namespace std;
inline int read(){
int f=1,r=0;char c=getchar();
while(!isdigit(c))f^=c=='-',c=getchar();
while(isdigit(c))r=(r<<1)+(r<<3)+(c&15),c=getchar();
return f?r:-r;
}
const int N=1e5+7;
struct Plane{
int x,y;
bool operator < (const Plane &q) const {return x<q.x;}
}a[N],b[N];
int n,m1,m2,pa[N],A[N],B[N];
int find(int x){return pa[x]^x?pa[x]=find(pa[x]):x;}
bool vis[N];
inline void get(int m,Plane *a,int *ans){
for(int i=1;i<=m;i++)vis[i]=0;
for(int i=1;i<=m+1;i++)pa[i]=i;
for(int j=1;j<=n;j++){
ans[j]=ans[j-1];
if(ans[j]==m)continue;
int i=find(1);
while(i<=m){
ans[j]++;
int l=i+1,r=m;
while(l<=r){
int mid=(l+r)>>1;
if(a[mid].x>a[i].y)r=mid-1;
else l=mid+1;
}
l=find(l),pa[i]=find(i+1),i=l;
}
}
}
int main(){
freopen("airport.in","r",stdin);
freopen("airport.out","w",stdout);
n=read(),m1=read(),m2=read();
if(n>=m1+m2)printf("%d\n",m1+m2),exit(0);
for(int i=1;i<=m1;i++)a[i].x=read(),a[i].y=read();
for(int i=1;i<=m2;i++)b[i].x=read(),b[i].y=read();
sort(a+1,a+m1+1),sort(b+1,b+m2+1);
get(m1,a,A),get(m2,b,B);int ans=0;
for(int i=0;i<=n;i++)ans=max(ans,A[i]+B[n-i]);
printf("%d\n",ans);
return 0;
}