P7913 [CSP-S 2021] 廊桥分配
题目

分析
考场傻逼了,知道性质都没做出来。
我们发现如果对于拥有 \(i\) 个廊桥来说,如果我们当前有 \(i+1\) 个,那么原来会停在廊桥的飞机一定还是会停在廊桥。
于是就很好做了,每次多了一个廊桥一定是会减少当前的一些线段(把每一个飞机的 到达-离开 时间看做是线段)。
这个很好维护,直接使用 set。
那么我们就可以算出每一个飞机最先会在什么时候开始停在廊桥。
显然就是个值域上的匹配了,扫描一下值域取 \(\max\) 即可。
时间复杂度 \(O(n\log n)\) 。
代码
#include<bits/stdc++.h>
using namespace std;
#ifdef ONLINE_JUDGE
#define getchar() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++)
char buf[1<<21],*p1=buf,*p2=buf;
#endif
template<typename T>
inline void read(T &x){
x=0;bool f=false;char ch=getchar();
while(!isdigit(ch)){f|=ch=='-';ch=getchar();}
while(isdigit(ch)){x=x*10+(ch^48);ch=getchar();}
x=f?-x:x;
return ;
}
template<typename T>
inline void write(T x){
if(x<0) x=-x,putchar('-');
if(x>9) write(x/10);
putchar(x%10^48);
return ;
}
#define ll long long
#define ull unsigned long long
#define ld long double
#define pb push_back
#define mp make_pair
#define fi first
#define se second
#define pc putchar
#define PII pair<int,int>
#define rep(i,x,y) for(register int i=(x);i<=(y);i++)
#define dep(i,y,x) for(register int i=(y);i>=(x);i--)
const int MOD=1e9+7;
inline int inc(int x,int y){x+=y;return x>=MOD?x-MOD:x;}
inline int dec(int x,int y){x-=y;return x<0?x+MOD:x;}
inline void incc(int &x,int y){x+=y;if(x>=MOD) x-=MOD;}
inline void decc(int &x,int y){x-=y;if(x<0) x+=MOD;}
inline void chkmin(int &x,int y){if(y<x) x=y;}
inline void chkmax(int &x,int y){if(y>x) x=y;}
const int N=1e5+5,M=2e5+5,INF=1e9+7;
int st[N],ed[N],dp1[N],dp2[N];
int n,m1,m2,t1[N],t2[N],Ans;
set<PII>S1,S2;
signed main(){
// freopen(".in","r",stdin);
// freopen(".out","w",stdout);
// ios::sync_with_stdio(false);
// double ST=clock();
read(n),read(m1),read(m2);
for(int i=1,x,y;i<=m1;i++) read(st[i]),read(ed[i]),S1.insert(mp(st[i],i));
for(int i=1;i<=m1;i++){
set<PII>::iterator itl,itr;
itr=S1.begin();
while(itr!=S1.end()){
dp1[(*itr).se]=i;
int id=(*itr).se;
S1.erase(itr);
itr=S1.lower_bound(mp(ed[id],id));
}
}
for(int i=1,x,y;i<=m2;i++) read(st[i]),read(ed[i]),S1.insert(mp(st[i],i));
for(int i=1;i<=m2;i++){
set<PII>::iterator itl,itr;itr=S1.begin();
while(itr!=S1.end()){
dp2[(*itr).se]=i;
int id=(*itr).se;
S1.erase(itr);
itr=S1.lower_bound(mp(ed[id],id));
}
}
for(int i=1;i<=m1;i++) t1[dp1[i]]++;
for(int i=1;i<=m2;i++) t2[dp2[i]]++;
for(int i=1;i<=n;i++) t1[i]+=t1[i-1],t2[i]+=t2[i-1];
for(int i=1;i<=n;i++) Ans=max(Ans,t1[min(m1,i)]+t2[min(m2,n-i)]);
write(Ans);
#ifndef ONLINE_JUDGE
cerr<<"\nTime:"<<(clock()-ST)/CLOCKS_PER_SEC<<"s\n";
#endif
return 0;
}
/*
*/

浙公网安备 33010602011771号