牛客数据结构队列训练题 蚯蚓
啊啊啊,好怀念,2016年的NOIP的试题,欸,当时我还是个小白,现在也是菜鸡,这道用三个队列即可完成
首先,我们来分析下对于每对 x1,x2(x1>x2) 他们被剪断后的操作
1、对于每一对x1,x2(x1>x2):
p1=x1p , p2=x1-x1p;
p3=x2p , p4=x2-x2p;
明显p1>=p3,p2>=p4;
2、在剪断x1 t秒后再剪断x2
p1=x1p+qt , p2=x1-x1p+qt;
p3=(x2+qt)p , p4=(x2+qt)-(x2+qt)*p;
同样明显p1>=p3,p2>=p4;
也就是说最先剪断并保存下来的,一定比之后剪断保存下来的先接受 咔嚓;
我们开三个数组(队列),第一个存储原来长度的顺序,第二个保存剪断后的p1,第三个保存剪断后的p2;
后面两个的存储顺序由上面证明的结论说明,每次添加只需要往队列后添加即可。
上代码:
#include <bits/stdc++.h>
#define ll long long
const int maxn=8e6+7;
using namespace std;
struct line{
ll len;
int ti;
}qy[3][maxn];
int n,m,q,u,v,t;
int l[3],r[3];
bool cmp(line a,line b){
return a.len>b.len;
}
int main()
{
scanf("%d %d %d %d %d %d",&n,&m,&q,&u,&v,&t);
for(int i=1;i<=n;i++){
scanf("%lld",&qy[0][i].len);
qy[0][i].ti=0;
}
sort(qy[0]+1,qy[0]+1+n,cmp);
l[0]=l[1]=l[2]=1,r[0]=n,r[1]=r[2]=0;
for(int i=1;i<=m;i++){
ll zlen=-0x7fffffff,k;
for(int j=0;j<3;j++){
if(l[j]<=r[j] && qy[j][l[j]].len+(i-qy[j][l[j]].ti-1)*q>zlen){
zlen=qy[j][l[j]].len+(i-qy[j][l[j]].ti-1)*q;
k=j;
}
}
if(i%t==0)
printf("%lld ",zlen);
l[k]++;
qy[1][++r[1]].len=zlen*u/v , qy[1][r[1]].ti=i;
qy[2][++r[2]].len=zlen-qy[1][r[1]].len , qy[2][r[2]].ti=i;
}
cout<<endl;
for(int i=1;i<=n+m;i++){
ll zlen=-0x7fffffff,k;
for(int j=0;j<3;j++){
if(l[j]<=r[j] && qy[j][l[j]].len+(m-qy[j][l[j]].ti)*q>zlen){
zlen=qy[j][l[j]].len+(m-qy[j][l[j]].ti)*q;
k=j;
}
}
if(i%t==0)
printf("%lld ",zlen);
l[k]++;
}
return 0;
}