题目传送门:传送门
对于该题,显然我们可以考虑维护 $sum1_i$ 表示给国内区分配 $i$ 个廊桥能停靠的最多飞机数,同理考虑维护 $sum2_i$ 表示给国际区分配 $i$ 个廊桥能停靠的最多飞机数。
此时显然会有 $ans=max(ans,sum1_{i}+sum2_{n-i})$ ,注意到此时 $i$ 的取值范围为 $[0,n]$。
再考虑如何维护 $sum1_i$ 与 $sum2_i$,显然对于国内区和国际区的航班处理属于同构问题,考虑处理一个即可。
对于国内区的航班,遵循“先到先得原则”,将航班按照到达时间先后排序。每次到达一个航班,我们将其分配给当前空闲的编号最小的廊桥,并把该廊桥设为已用。当该航班离开时,再将此廊桥设为空闲。显然这种贪心策略可以使用对顶堆进行实现。此时我们得到了,每个廊桥停靠的飞机编号及其数量,对廊桥停靠的飞机数量做前缀和即可得到我们想要维护的 $sum1_i$。国际区同理。总的时间复杂度为 $O(n + mlogm)$
1 #include<bits/stdc++.h> 2 #define int long long 3 using namespace std; 4 const int N = 100000 + 10; 5 struct arrive 6 { 7 int ls,rs; 8 }a[N],b[N]; 9 typedef pair<int,int> point; 10 priority_queue < point,vector < point >,greater < point> > plane; 11 priority_queue< int,vector < int >,greater < int > > port; 12 int n,m1,m2,ans; 13 int f[N],g[N]; 14 int sum1[N],sum2[N]; 15 bool cmp(arrive aa,arrive bb) 16 { 17 return aa.ls < bb.ls; 18 } 19 signed main() 20 { 21 scanf("%lld%lld%lld",&n,&m1,&m2); 22 for(int i = 1;i <= m1;i++) scanf("%lld%lld",&a[i].ls,&a[i].rs); 23 for(int i = 1;i <= m2;i++) scanf("%lld%lld",&b[i].ls,&b[i].rs); 24 sort(a + 1,a + m1 + 1,cmp); 25 sort(b + 1,b + m2 + 1,cmp); 26 for(int i = 1;i <= n;i++) port.push(i); 27 for(int i = 1;i <= m1;i++) 28 { 29 while(not plane.empty() and a[i].ls >= plane.top().first) 30 { 31 port.push(plane.top().second); 32 plane.pop(); 33 } 34 if(port.empty()) continue; 35 int pos = port.top(); 36 port.pop(); 37 f[pos]++; 38 plane.push(make_pair(a[i].rs,pos)); 39 } 40 while(not port.empty()) port.pop(); 41 while(not plane.empty()) plane.pop(); 42 for(int i = 1;i <= n;i++) port.push(i); 43 for(int i = 1;i <= m2;i++) 44 { 45 while(not plane.empty() and b[i].ls >= plane.top().first) 46 { 47 port.push(plane.top().second); 48 plane.pop(); 49 } 50 if(port.empty()) continue; 51 int pos = port.top(); 52 port.pop(); 53 g[pos]++; 54 plane.push(make_pair(b[i].rs,pos)); 55 } 56 for(int i = 1;i <= n;i++) sum1[i] = sum1[i-1] + f[i]; 57 for(int i = 1;i <= n;i++) sum2[i] = sum2[i-1] + g[i]; 58 for(int i = 0;i <= n;i++) ans = max(ans,sum1[i] + sum2[n-i]); 59 printf("%lld\n",ans); 60 return 0; 61 }View Code