CSP-S 2021 T1 廊橋分配 題解


題目傳送門

跟大部分人想法一致,只不過預處理貢獻時使用的二分+並查集而不是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;
}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM