题解:P2827 [NOIP 2016 提高组] 蚯蚓
pipilong2024 · · 题解
经 Jayne(老师,不敢@)和 @Lyzc0dr 的激烈讨论,得出来一种新做法。
首先我们明白一个不等式
根据这个不等式,我们可以考虑维护三个队列,而不必维护一个优先队列,因为三个队列始终保持满足单调性,无需使用优先队列(此处和其他 TJ 相同)。
然后根据此思路即可拿到所有
考虑到一条在第
那么具体做法请看代码:
#include <bits/stdc++.h>
using namespace std;
#define int long long
#define pii pair<int,int>
const int maxn=2e5+10;
int n,m,Q,u,v,t,a[maxn];
queue<pii>q[4];//ABC三个队列
int get_max_len(int time){//取出最长的蚯蚓
int x=-1e9,y=-1e9,z=-1e9;
if(!q[1].empty())x=q[1].front().first+Q*(time-1-q[1].front().second);
if(!q[2].empty())y=q[2].front().first+Q*(time-1-q[2].front().second);
if(!q[3].empty())z=q[3].front().first+Q*(time-1-q[3].front().second);
//分别取出三个队列队首
int idx=1LL,tmp=0LL;//idx表示取出来哪一个队列的队首,tmp表示最大的队首
if(x>=y && x>=z) tmp=x,idx=1;
if(y>=x && y>=z) tmp=y,idx=2;
if(z>=x && z>=y) tmp=z,idx=3;
//更新tmp和idx
q[idx].pop();//弹出
return tmp;
}
signed main() {
ios::sync_with_stdio(false);
cin.tie(0),cout.tie(0);
cin>>n>>m>>Q>>u>>v>>t;
for(int i=1;i<=n;i++) cin>>a[i];
sort(a+1,a+n+1);//正序排序(从小到大)
for(int i=n;i>=1;i--) q[1].push({a[i],0});//倒序加入(从大到小)
for(int i=1;i<=m;i++){
int len=get_max_len(i),x,y;
x=len*u/v,y=len-x;//分段
if(i%t==0) cout<<len<<" ";//输出
q[2].push({x,i}),q[3].push({y,i});//同其他TJ,加入B,C两个队列,始终保持单调
}
cout<<"\n";//换行
for(int i=1;;i++){
if(q[1].empty() && q[2].empty() && q[3].empty()) break;//三个队列都空了就停止
int tmp=get_max_len(m+1);//继续获取最大的蚯蚓
if(i%t==0) cout<<tmp<<" ";//输出
}
return 0;
}