看见了这个题面但是忽略了很重要的一句:我们的飞机对一廊桥来讲是先到先得的.
因为我没看见这个重要条件`,所以我采用了单调队列的做法(我的做法是合并两个飞机(我的'飞机'可能是两个及以上)然后左右端点合并,以飞机数优先(让数量单调增)),很显然是fake的,在这之前我想过三分以及dp的,但是鉴于数据范围dp很显然不是,然后更明显的这个函数不是单峰的(因为有国内和国外两个航班)
后续待更
#include<bits/stdc++.h> using namespace std; const int N=1e5+7; int n,m1,m2; struct node { int l,r; }a1[N],a2[N]; int cnt; bool cmp(node x,node y) { if(x.l==y.l) return x.r<y.r; else return x.l<y.l; } priority_queue< pair<int ,int > >q; priority_queue< int >qid; int v[N]; int siz1[N],siz2[N]; void init() { for(int i=1;i<=n;i++) siz1[i]+=siz1[i-1]; while(q.size()) q.pop(); while(qid.size()) qid.pop(); for(int i=1;i<=n;i++) qid.push(-i); cnt=0; return ; } int maxx; int main() { ios::sync_with_stdio(false); cin>>n>>m1>>m2; for(int i=1;i<=m1;i++) { cin>>a1[i].l>>a1[i].r; } for(int i=1;i<=m2;i++) { cin>>a2[i].l>>a2[i].r; } sort(a1+1,a1+1+m1,cmp); sort(a2+1,a2+1+m2,cmp); for(int i=1;i<=n;i++) { qid.push(-i); } for(int i=1;i<=m1;i++) { if(cnt) { while(cnt&&-q.top().first<a1[i].l) { cnt--; qid.push(-q.top().second); q.pop(); } } if(qid.size()) { int pos=-qid.top(); qid.pop(); siz1[pos]++; q.push({-a1[i].r,pos}); cnt++; } } init(); for(int i=1;i<=m2;i++) { if(cnt) { while(cnt&&-q.top().first<a2[i].l) { cnt--; qid.push(-q.top().second); q.pop(); } } if(qid.size()) { int pos=-qid.top(); qid.pop(); siz2[pos]++; q.push({-a2[i].r,pos}); cnt++; } } for(int i=1;i<=n;i++) siz2[i]+=siz2[i-1]; for(int i=0;i<=n;i++) { maxx=max(maxx,siz1[i]+siz2[n-i]); } cout<<maxx; return 0; }