【题解】[NOIP2016 提高组] 蚯蚓
\(\text{Solution:}\)
观察到 \(m\) 的范围就知道了不能堆硬上了,考虑去掉 \(\log.\)
发现,每次切下来的蚯蚓是有单调性的。所以能不能用一个队列去特殊维护切下来的蚯蚓?
可以,但是我们发现那个 \(\frac{u}{v}=q\not=\frac{1}{2},\) 所以它们是分别呈单调性,所以需要用两个队列来维护蚯蚓长度。
我们发现这两个蚯蚓长度都是单调的,所以就可以用 双端队列 来去掉这个 $\log $ 了。
然后注意一下分类讨论和输出格式。关于每次的增长我们考虑维护一个全局增长量,注意一下题目说的切下来的蚯蚓不增长,把对应增长量去掉即可。
剩下的就是注意一下初始值要特别小才可以,以及数组不要开小,还有输出格式。
#include<bits/stdc++.h>
using namespace std;
#define int long long
const int N=7e6+10;
deque<int>q[3];
int n,m,Q,u,v,t;
int a[N];
int tag,ts;
inline int Max(int x,int y){return x>y?x:y;}
vector<int>Ans,qy;
inline bool cmp(int x,int y){return x>y;}
signed main(){
scanf("%lld%lld%lld%lld%lld%lld",&n,&m,&Q,&u,&v,&t);
for(int i=1;i<=n;++i)scanf("%lld",&a[i]);
sort(a+1,a+n+1);
for(int i=1;i<=n;++i)q[0].push_front(a[i]);
//q[0]:Natural
//q[1]:Cut_Long
//q[2]:Cut_Short
while(m--){
ts++;
int t0=-(1LL<<60),t1=-(1LL<<60),t2=-(1LL<<60);
if(!q[0].empty())t0=q[0].front();
if(!q[1].empty())t1=q[1].front();
if(!q[2].empty())t2=q[2].front();
t0+=tag;
t1+=tag;
t2+=tag;
int mx=Max(t1,Max(t0,t2));
// printf("mx:%d\n",mx);
if(t0==mx){
q[0].pop_front();
int p1=(t0*u/v);
int p2=t0-p1;
if(p1<p2)swap(p1,p2);
p1-=tag;p2-=tag;
p1-=Q;p2-=Q;
q[1].push_back(p1);
q[2].push_back(p2);
// printf("(%d %d)\n",p1+tag,p2+tag);
}
else if(t1==mx){
q[1].pop_front();
int p1=(t1*u/v);
int p2=t1-p1;
if(p1<p2)swap(p1,p2);
p1-=tag;p2-=tag;
p1-=Q;p2-=Q;
q[1].push_back(p1);
q[2].push_back(p2);
// printf("(%d %d)\n",p1+tag,p2+tag);
}
else if(t2==mx){
q[2].pop_front();
int p1=(t2*u/v);
int p2=t2-p1;
if(p1<p2)swap(p1,p2);
p1-=tag;p2-=tag;
p1-=Q;p2-=Q;
q[1].push_back(p1);
q[2].push_back(p2);
// printf("(%d %d)\n",p1+tag,p2+tag);
}
tag+=Q;
if(ts%t==0)Ans.push_back(mx);//,puts("fk");
}
for(auto v:Ans)printf("%lld ",v);
puts("");
for(auto v:q[0])qy.push_back(v+tag);
for(auto v:q[1])qy.push_back(v+tag);
for(auto v:q[2])qy.push_back(v+tag);
sort(qy.begin(),qy.end(),cmp);
for(int i=0;i<(int)qy.size();++i){
int rk=i+1;
if(rk%t==0)printf("%lld ",qy[i]);
}
return 0;
}