题意
一开始有 n n n 条蚯蚓,每次取出最长的蚯蚓,然后切成两段,一段为 u v × l i \frac{u}{v}\times l_i vu×li,另一段为剩下的,同时其他的蚯蚓都会增长 q q q ,然后询问你在 t , 2 t , 3 t , 4 t , 5 t . . . t,2t,3t,4t,5t... t,2t,3t,4t,5t...时刻取出的蚯蚓长度和 m m m 次操作后第 t , 2 t , 3 t … … t,2t,3t…… t,2t,3t……长的蚯蚓的长度。
解题方法
这个题一看去就会一个 o ( n log 2 n ) o(n\log_2n) o(nlog2n)的算法,就是每次用一个堆来维护,然后发现时间复杂度无法满足,然后我们就只能通过观察每次切出来两个的蚯蚓的性质来做题了,我们先假设出一个长度为 x x x 和长度为 y y y 的蚯蚓,然后我们列出来最终蚯蚓的长度: [ x × p ] + q , [ ( y + q ) × p ] , x + q − [ x × p ] , ( y + q ) − [ ( y + q ) × p ] [x\times p]+q,[(y+q) \times p], x+q-[x \times p],(y+q)-[(y+q) \times p] [x×p]+q,[(y+q)×p],x+q−[x×p],(y+q)−[(y+q)×p],我们发现 [ x × p ] + q ≥ [ ( x + q ) × p ] ≥ [ ( y + q ) × p ] [x \times p]+q \geq[(x+q) \times p] \geq[(y+q) \times p] [x×p]+q≥[(x+q)×p]≥[(y+q)×p]和 x + q − [ x × p ] ≥ ( y + q ) − [ ( y + q ) × p ] x+q-[x \times p] \geq(y+q)-[(y+q) \times p] x+q−[x×p]≥(y+q)−[(y+q)×p],所以说当 x > y x>y x>y时,切出来的蚯蚓对应的也是大于的,所以我们就想出用三个队列,一个用来存原来的蚯蚓,另外两个分别存切开的蚯蚓,然后每次我们取出三个队列的队首,把最大的切了,就可以解决了这个问题了。
代码
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
using namespace std;
queue<int>q[4];
long long a[210000];
bool comp(long long x,long long y)
{
return x>y;
}
long long n,m,qq,u,v,t;
int main()
{
scanf("%lld%lld%lld%lld%lld%lld",&n,&m,&qq,&u,&v,&t);
for(long long i=1;i<=n;i++)
{
scanf("%lld",&a[i]);
}
sort(a+1,a+n+1,comp);
for(long long i=1;i<=n;i++)
q[1].push(a[i]);
for(long long i=1;i<=m;i++)
{
long long nowj,maxn;
maxn=-1e9;
for(long long j=1;j<=3;j++)
{
if(!q[j].size())continue;
if(q[j].front()>maxn)
{
maxn=q[j].front();
nowj=j;
}
}
q[nowj].pop();
if(i%t==0)cout<<(i-1)*qq+maxn<<' ';
long long deta=(i-1)*qq;
long long x1=(int)1.0*(maxn+deta)*u/v-i*qq;
long long x2=maxn+deta-(int)1.0*(maxn+deta)*u/v-i*qq;
q[2].push(x1);
q[3].push(x2);
}
puts("");
for(long long i=1;i<=n+m;i++)
{
long long nowj,maxn;
maxn=-1e9;
for(long long j=1;j<=3;j++)
{
if(!q[j].size())continue;
if(q[j].front()>maxn)
{
maxn=q[j].front();
nowj=j;
}
}
q[nowj].pop();
if(i%t==0)cout<<m*qq+maxn<<' ';
}
return 0;
}