pts85/90(90应该是个意外,第一次交是90之后都是85了):
优先队列模拟题意

#include<iostream>
#include<cstdio>
#include<queue>
using namespace std;
int n,m,q,u,v,t,tim;
double p;
priority_queue<int>qq;
int main()
{
scanf("%d%d%d%d%d%d",&n,&m,&q,&u,&v,&t);
p=1.0*u/(1.0*v);
for(int i=1,x;i<=n;i++){
scanf("%d",&x);
qq.push(x);
}
while(m--){
tim++;
int x=qq.top();
qq.pop();
if(tim%t==0)printf("%d ",x+(tim-1)*q);
int y=(int)(p*(double)(x+(tim-1)*q));
x=(x+(tim-1)*q)-y;
qq.push(x-tim*q),qq.push(y-tim*q);
}
printf("\n");
int now=0;
while(qq.size()){
now++;
if(now%t==0){
printf("%d ",qq.top()+tim*q);
}
qq.pop();
}
return 0;
}
顺手练一下手写二叉堆

#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
int n,m,q,u,v,t,tim,a[16*1000010],num;
double p;
bool cmp(int x,int y){
return x>y;
}
int main()
{
scanf("%d%d%d%d%d%d",&n,&m,&q,&u,&v,&t);
p=1.0*u/(1.0*v);
for(int i=1,x;i<=n;i++){
scanf("%d",&a[i]);
x=i;
while(x>1&&a[x]>a[x>>1]){
swap(a[x],a[x>>1]);
x>>=1;
}
}
while(m--){
tim++;
int x=a[1];
if(tim%t==0)printf("%d ",x+(tim-1)*q);
int y=(int)(p*(double)(x+(tim-1)*q));
x=(x+(tim-1)*q)-y;
a[1]=x-tim*q;
int now=1;
while((a[now]<a[now<<1]||a[now]<a[now<<1|1])&&(now<<1|1)<=n){
if(a[now<<1]<a[now<<1|1]){
swap(a[now],a[now<<1|1]);
now<<=1;
now|=1;
}
else{
swap(a[now],a[now<<1]);
now<<=1;
}
}
if(a[now]<a[now<<1]&&(now<<1)<=n){
swap(a[now],a[now<<1]);
}
a[++n]=y-tim*q;
now=n;
while(now>1&&a[now]>a[now>>1]){
swap(a[now],a[now>>1]);
now>>=1;
}
}
printf("\n");
sort(a+1,a+n+1,cmp);
for(int i=1;i<=n;i++){
if(i%t==0){
printf("%d ",a[i]+tim*q);
}
}
return 0;
}
正解:
发现先切的蚯蚓产生的长段永远不小于后切的蚯蚓产生的长段,短段也是。因为从准备切先切的开始,后切的生长t个单位长度的同时,先前切好的两段都生长了t-1个单位长度。
切好的长段集合和短段集合本身就具有单调性。
用三个队列分别储存未切的,切好的长段,切好的短段,每次从三个队头寻找最大的进行操作。

#include<iostream>
#include<cstdio>
#include<queue>
#include<algorithm>
using namespace std;
int n,m,q,u,v,t,tim,maxx,pos,a[8*1000010],inf=214748364;
double p;
queue<int>qq[3];
bool cmp(int x,int y){
return x>y;
}
int main()
{
scanf("%d%d%d%d%d%d",&n,&m,&q,&u,&v,&t);
p=1.0*u/(1.0*v);
for(int i=1;i<=n;i++){
scanf("%d",&a[i]);
}
sort(a+1,a+n+1);
for(int i=n;i>=1;i--)qq[0].push(a[i]);
while(m--){
tim++;
maxx=pos=-inf;
if(qq[0].front()>maxx&&qq[0].size())maxx=qq[0].front(),pos=0;
if(qq[1].front()>maxx&&qq[1].size())maxx=qq[1].front(),pos=1;
if(qq[2].front()>maxx&&qq[2].size())maxx=qq[2].front(),pos=2;
qq[pos].pop();
if(tim%t==0)printf("%d ",maxx+(tim-1)*q);
int y=(int)(p*(double)(maxx+(tim-1)*q));
maxx=(maxx+(tim-1)*q)-y;
qq[1].push(max(maxx,y)-tim*q),qq[2].push(min(maxx,y)-tim*q);
}
printf("\n");
n=0;
while(qq[0].size()){
a[++n]=qq[0].front();
qq[0].pop();
}
while(qq[1].size()){
a[++n]=qq[1].front();
qq[1].pop();
}
while(qq[2].size()){
a[++n]=qq[2].front();
qq[2].pop();
}
sort(a+1,a+n+1,cmp);
for(int i=1;i<=n;i++){
if(i%t==0){
printf("%d ",a[i]+tim*q);
}
}
return 0;
}
