[牛客小白月赛18] Forsaken的数列

FHQTreap裸题...

用文艺平衡树的方法,维护区间和然后一直Push_Down就可以了(60行代码暴力AC)

 1 //张家奇怎么又AKIOI了呀,怎么CSP也满分啊...怎么清北天天给他打电话啊...怎么会有这么强的人啊
 2 #include<bits/stdc++.h>
 3 #define int long long
 4 #define writeln(x)  write(x),puts("")
 5 #define writep(x)   write(x),putchar(' ')
 6 using namespace std;
 7 inline int read(){
 8     int ans=0,f=1;char chr=getchar();
 9     while(!isdigit(chr)){if(chr=='-') f=-1;chr=getchar();}
10     while(isdigit(chr)){ans=(ans<<3)+(ans<<1)+chr-48;chr=getchar();}
11     return ans*f;
12 }void write(int x){
13     if(x<0) putchar('-'),x=-x;
14     if(x>9) write(x/10);
15     putchar(x%10+'0');
16 }const int M = 2E5+5;
17 int n,m,cnt,x,y,z,root;
18 struct FHQ_Treap{int x,ls,rs,sz,lz,sum,key;}s[M];
19 inline int NewNode(int val){s[++cnt]=(FHQ_Treap){val,0,0,1,0,val,rand()};return cnt;}
20 inline void Push_Up(int i){s[i].sum=s[s[i].ls].sum+s[s[i].rs].sum+s[i].x;s[i].sz=s[s[i].ls].sz+s[s[i].rs].sz+1;}
21 inline void Push_Down(int i){
22     if(!s[i].lz) return;
23     s[s[i].ls].lz+=s[i].lz,s[s[i].rs].lz+=s[i].lz;
24     s[s[i].ls].x+=s[i].lz,s[s[i].rs].x+=s[i].lz;
25     s[s[i].ls].sum+=s[i].lz*s[s[i].ls].sz;
26     s[s[i].rs].sum+=s[i].lz*s[s[i].rs].sz;
27     s[i].lz=0;
28 }int Merge(int x,int y){
29     if(s[x].lz)Push_Down(x);
30     if(s[y].lz)Push_Down(y);
31     if(!x||!y)return x+y;
32     if(s[x].key<s[y].key)return s[x].rs=Merge(s[x].rs,y),Push_Up(x),x;
33     else return s[y].ls=Merge(x,s[y].ls),Push_Up(y),y;
34 }void Split(int now,int size,int &x,int &y){
35     if(!now)return x=y=0,void();
36     Push_Down(now);
37     if(s[s[now].ls].sz>=size) y=now,Split(s[now].ls,size,x,s[now].ls);
38     else x=now,Split(s[now].rs,size-s[s[now].ls].sz-1,s[now].rs,y);
39     Push_Up(now);
40 }inline void Insert(int val,int pos){
41     Split(root,pos-1,x,y);
42     root=Merge(Merge(x,NewNode(val)),y);
43 }inline void Add(int l,int r,int val){
44     Split(root,r,x,z),Split(x,l-1,x,y);
45     s[y].x+=val,s[y].lz+=val,s[y].sum+=val*s[y].sz;
46     root=Merge(Merge(x,y),z);
47 }inline int Query(int l,int r){
48     Split(root,r,x,z);Split(x,l-1,x,y);
49     printf("%lld\n",s[y].sum);
50     root=Merge(Merge(x,y),z);
51 }signed main(){n=read();srand(1919810);
52     for(int x,i(1);i<=n;i++)x=read(),Insert(x,i);
53     int T=read();
54     while(T--){
55         int opt=read(),pos,l,r;
56         if(opt==1)pos=read(),Insert(0,pos);
57         if(opt==2)l=read(),r=read(),pos=read(),Add(l,r,pos);
58         if(opt==3)l=read(),r=read(),Query(l,r);
59     }return 0;
60 }

 

posted @ 2019-10-29 18:27  zheng_liwen  阅读(263)  评论(0编辑  收藏  举报
/*去广告*/