题目传送门:https://www.luogu.org/problemnew/show/P2827
自测时被题面所误导...,题面中说逢t的倍数才输出答案,以为有什么玄妙的方法直接将m次操作变成了m/t次操作。结果GG....
65分做法:写一个左偏树,每次取出最顶端元素,对堆中其余元素全部+q(可以用标记完成),将该元素取出后,切为两段后再丢入该树中。时间复杂度为O((m+n) log m)。
幸好我不会65分的STL做法,据说此题有人用STL被卡了5分.....
1 #include<iostream> 2 #include<cstdio> 3 #include<queue> 4 #include<cstring> 5 #define M 1100000 6 using namespace std; 7 priority_queue<int> Q; 8 int n,m,q,t; 9 int tag[M]={0},a[M]={0},lc[M]={0},rc[M]={0}; 10 11 void pushdown(int x){ 12 if(!tag[x]) return; 13 tag[lc[x]]+=tag[x]; tag[rc[x]]+=tag[x]; 14 a[lc[x]]+=tag[x]; a[rc[x]]+=tag[x]; 15 tag[x]=0; 16 } 17 int merge(int x,int y){ 18 if(!x) return y; 19 if(!y) return x; 20 if(a[x]>a[y]){ 21 pushdown(x); 22 rc[x]=merge(rc[x],y); 23 swap(lc[x],rc[x]); 24 return x; 25 }else{ 26 pushdown(y); 27 lc[y]=merge(x,lc[y]); 28 swap(lc[y],rc[y]); 29 return y; 30 } 31 } 32 int rt=0,use=0; 33 long long v,u; 34 int main(){ 35 freopen("earthworm.in","r",stdin); 36 freopen("earthworm.out","w",stdout); 37 cin>>n>>m>>q>>u>>v>>t; 38 for(int i=1;i<=n;i++){ 39 int x; scanf("%d",&x); 40 use++; a[use]=x; 41 rt=merge(use,rt); 42 } 43 for(int i=1;i<=m;i++){ 44 int x=a[rt],lastrt=rt; 45 rt=merge(lc[rt],rc[rt]); 46 tag[rt]+=q; a[rt]+=q; 47 if(i%t==0) printf("%d ",x); 48 int x1=(u*x)/v,x2=x-x1; 49 lc[lastrt]=rc[lastrt]=0; a[lastrt]=x1; 50 rt=merge(rt,lastrt); 51 use++; a[use]=x2; 52 rt=merge(use,rt); 53 } 54 printf("\n"); 55 for(int i=1;i<=m+n;i++){ 56 int x=a[rt]; rt=merge(lc[rt],rc[rt]); 57 if(i%t==0) printf("%d ",x); 58 } 59 printf("\n"); 60 }