问题描述:给定一个长度为n的序列,对于每一个时刻,从序列中选出最大值裂成两个数
xq 和x - xq 其中 q 等于两个给定 u v 的商。 问过了时间 m 之后 序列的情况 (从大到小排序) 以及每隔 t 时刻对哪个数下手了。
题解:因为大的数裂开一定比小的数裂开的大,时间其实对大小的影响是没有的。
开三个 队列 A B C 。
其中A 存的是开始的序列 B 存的是 裂开后 xq 部分。 C 存的是 x-xq 部分。 证明三个队列的单调性可以证明(借其他人的博客??)
每次从三个队列中选出最大值 裂开 插入 B C 中
注意插入的是没有随时间变化的长度。因为所有的增长都可以最后统一处理。
详见代码:
#include<bits/stdc++.h>
#define ll long long
using namespace std;
queue<ll>A,B,C;
int n,m,q,u,v,t,a[100010];
bool myc(int x,int y) {return x>y;}
ll find(int T)
{
ll X=-1,Y=-1,Z=-1;
if(A.size()) X=A.front()+(ll)T*q;
if(B.size()) Y=B.front()+(ll)T*q;
if(C.size()) Z=C.front()+(ll)T*q;
if(X>=Y&&X>=Z) {A.pop(); return X;}
if(Y>=X&&Y>=Z) {B.pop(); return Y;}
if(Z>=X&&Z>=Y) {C.pop(); return Z;}
}
int main()
{
cin>>n>>m>>q>>u>>v>>t;
for(int i=1;i<=n;i++) scanf("%d",&a[i]);
sort(a+1,a+n+1,myc);
for(int i=1;i<=n;i++) A.push((ll)a[i]);
for(int i=1;i<=m;i++)
{
ll x=find(i-1);
if(i%t==0) printf("%lld ",x);
B.push(1LL*x*u/v-i*q);
C.push(x-1LL*x*u/v-i*q);
}
puts("");
for(int i=1;i<=n+m;i++)
{
ll x=find(m);
if(i%t==0) printf("%lld ",x);
}
return 0;
}