版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
- 题目大意:给定一个数列,从中选出最大的一个数x然后变为 和 ,其余数加q,重复m(7e6)次,问m次后数列
- 思路:
- 可以从m的大小看出需要O(m)求出答案,于是思考线性算法
- 除了新生成的两个数其余全加,可以换个角度想,维护一个整体偏移值,其他数不加,新数减,可以将单次复杂度从O(n)降为O(1)。
- 在加上偏移值以后取出的数单减,所以产生的两个数分别单减,则先排序可以用三个单调队列维护(一个初始,两个存产生)
#include<bits/stdc++.h>
#define M 7000005
using namespace std;
int n,m,q,u,v,t,qa[100005],qb[M],qc[M],af,bf,cf,ab,bb,cb;
double p;
bool cmp(int a,int b)
{
return a>b;
}
int del;
int main()
{
scanf("%d%d%d%d%d%d",&n,&m,&q,&u,&v,&t);
p=double(u)/v;
for(int i=1;i<=n;i++)
scanf("%d",&qa[i]);
sort(qa+1,qa+1+n,cmp);
af=bf=cf=1;ab=n;
int mx,biao;
for(int i=1;i<=m;i++)
{
mx=-999999999;
if(af<=ab&&qa[af]>mx)
mx=qa[af],biao=1;
if(bf<=bb&&qb[bf]>mx)
mx=qb[bf],biao=2;
if(cf<=cb&&qc[cf]>mx)
mx=qc[cf],biao=3;
mx+=del;
if(i%t==0)
{
printf("%d ",mx);
}
biao==1&&af++;
biao==2&&bf++;
biao==3&&cf++;
qb[++bb]=floor(mx*p)-del-q;
qc[++cb]=mx-qb[bb]-del-q-del-q;
del+=q;
}
printf("\n");
for(int i=1;i<=n+m;i++)
{
mx=-999999999;
if(af<=ab&&qa[af]>mx)
mx=qa[af],biao=1;
if(bf<=bb&&qb[bf]>mx)
mx=qb[bf],biao=2;
if(cf<=cb&&qc[cf]>mx)
mx=qc[cf],biao=3;
if(i%t==0)
{
printf("%d ",mx+del);
}
biao==1&&af++;
biao==2&&bf++;
biao==3&&cf++;
}
}