[CSP-S 2021] 廊桥分配

1|0Problem

原题链接

2|0Solution

首先我们考虑如果廊桥足够用我们应当怎样安排飞机,是不是每一次来一架飞机,我们就安排它到空闲的且编号最小的廊桥,这就可以保证廊桥使用率最高,这是可以用堆去搞的。
然后如果有了限制,我们假设远机位也是廊桥,那么就是按照上面分配方法来分,如果有 m 个廊桥,那么前 m 个位置就是真的廊桥,后面的位置就是假廊桥。概括地说,每个位置,无论它是廊桥还是远机位,它的飞机数目是不变的。比如,现在有 m 个廊桥,变成 m+1 个廊桥后,无非就是把第 m+1 个位置,由原来的远机位变成廊桥。
所以我们就按照第一段的分配方法去搞,预处理前缀和,然后枚举国内分几个廊桥就可以了。
还有这里要用小根堆,我的做法是开大根堆,每次丢它的相反数进去就可以了,取出来再还原。
时间复杂度:O(nlogn)

3|0Code

#include<bits/stdc++.h> #define int long long using namespace std; void read(int &x) { char ch=getchar(); int r=0,w=1; while(!isdigit(ch))w=ch=='-'?-1:1,ch=getchar(); while(isdigit(ch))r=(r<<3)+(r<<1)+(ch^48),ch=getchar(); x=r*w; } const int N=1e6+7; struct node { int l,r; }a[N]; int s1[N],s2[N],n,m1,m2; void init(int *s,int m) { priority_queue<int>q; priority_queue<pair<int,int> >t; for(int i=1;i<=m;i++)q.push(-i); for(int i=1;i<=m;i++) { while(!t.empty()&&a[i].l>-t.top().first) { q.push(-t.top().second); t.pop(); } int u=-q.top();q.pop(); t.push(make_pair(-a[i].r,u)); s[u]++; } for(int i=1;i<=n;i++)s[i]+=s[i-1]; } bool cmp(node a,node b) {return a.l<b.l;} main() { read(n);read(m1);read(m2); for(int i=1;i<=m1;i++) read(a[i].l),read(a[i].r); sort(a+1,a+m1+1,cmp); init(s1,m1); for(int i=1;i<=m2;i++) read(a[i].l),read(a[i].r); sort(a+1,a+m2+1,cmp); init(s2,m2); int ans=0; for(int i=0;i<=n;i++) ans=max(ans,s1[i]+s2[n-i]); cout<<ans; return 0; }

4|0后记

马上要打人生第一次提高了,VP 一下去年提高,其实还是有思维难度,越来越难了,这也说明人类在不断进化,现在普及模拟赛难度都可以出到省选了。。。
最后祝我自己 CSP-S2022 RP++!!!


__EOF__

本文作者JMartin
本文链接https://www.cnblogs.com/LAK666/p/16530622.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。您的鼓励是博主的最大动力!
posted @   Epoch_L  阅读(369)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】
点击右上角即可分享
微信分享提示