题目传送门: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 }
很垃圾的65分代码

相关文章: