1 #include<bits/stdc++.h>
2 using namespace std;
3 const int MAX=5e5+20,INF=0x7fffffff;
4 struct ppp{
5 int val,ch[2],rnd,sum,lmax,rmax,mmax,size;
6 int change,reverse;
7 }treap[MAX];
8 int n,m,tot,root,name[MAX],st[MAX];
9 int read()
10 {
11 int tmp=0,fh=1; char c=getchar();
12 while ((c<‘0‘||c>‘9‘)&&c!=‘-‘) c=getchar();
13 if (c==‘-‘) fh=-1,c=getchar();
14 while (c>=‘0‘&&c<=‘9‘) tmp=tmp*10+c-48,c=getchar();
15 return tmp*fh;
16 }
17 inline int NEW(int val)
18 {
19 int p=name[tot--];
20 treap[p]=(ppp){val,0,0,rand(),0,0,0,0,0,0,0};
21 treap[p].val=val;
22 treap[p].rnd=rand();
23 treap[p].sum=val;
24 treap[p].lmax=treap[p].rmax=treap[p].mmax=val;
25 treap[p].size=1;
26 treap[p].change=INF;
27 return p;
28 }
29 inline void reuse(int p)
30 {
31 if(!p) return ;
32 name[++tot]=p;
33 reuse(treap[p].ch[0]);
34 reuse(treap[p].ch[1]);
35 }
36 inline void down(int p)
37 {
38 if(p==0) return;
39 if(treap[p].reverse)
40 {
41 treap[p].reverse=0;
42 swap(treap[p].ch[1],treap[p].ch[0]);
43 treap[treap[p].ch[0]].reverse^=1;
44 treap[treap[p].ch[1]].reverse^=1;
45 swap(treap[p].lmax,treap[p].rmax);
46 }
47 if(treap[p].change!=INF)
48 {
49 int k=treap[p].change;
50 treap[p].change=INF;
51 treap[p].rmax=treap[p].mmax=treap[p].lmax=(k>=0? k*treap[p].size:k);
52 treap[p].sum=treap[p].size*k;
53 treap[p].val=k;
54 treap[treap[p].ch[0]].change=k;
55 treap[treap[p].ch[1]].change=k;
56 }
57 }
58 inline void update(int p)
59 {
60 down(treap[p].ch[0]);
61 down(treap[p].ch[1]);
62 treap[p].sum=treap[p].val+treap[treap[p].ch[0]].sum+treap[treap[p].ch[1]].sum;
63 treap[p].size=treap[treap[p].ch[0]].size+treap[treap[p].ch[1]].size+1;
64 treap[p].lmax=max(treap[treap[p].ch[0]].lmax,treap[treap[p].ch[0]].sum+treap[p].val+max(0,treap[treap[p].ch[1]].lmax));
65 treap[p].rmax=max(treap[treap[p].ch[1]].rmax,treap[treap[p].ch[1]].sum+treap[p].val+max(0,treap[treap[p].ch[0]].rmax));
66 treap[p].mmax=max(max(treap[treap[p].ch[0]].mmax,treap[treap[p].ch[1]].mmax),treap[p].val+max(0,treap[treap[p].ch[0]].rmax)+max(0,treap[treap[p].ch[1]].lmax));
67 }
68
69 inline int build(int k)//笛卡尔树的建树方式 按照权值升序插入 O(n)
70 {
71 int tem_root,top=0;
72 tem_root=read();
73 tem_root=NEW(tem_root);
74 st[++top]=tem_root;
75 for(int i=1;i<k;i++)//k-1 次循环
76 {
77 int val;
78 val=read();
79 int p=NEW(val),last=0;
80 while(top and treap[st[top]].rnd>treap[p].rnd)//小根堆
81 {
82 treap[p].ch[0]=st[top];
83 update(st[top]);
84 top--;
85 }
86 if(top)
87 treap[st[top]].ch[1]=p;
88 else
89 tem_root=p;
90 st[++top]=p;
91 update(p);
92 }
93 while(top)
94 {
95 update(st[top]);
96 top--;
97 }
98 return tem_root;
99 }
100 inline void split(int now,int &x,int &y,int rank)
101 {
102 down(now);
103 if(rank>=treap[now].size)
104 {
105 x=now,y=0;
106 return ;
107 }
108 if(rank<=0)
109 {
110 y=now,x=0;
111 return ;
112 }
113 if(rank<=treap[treap[now].ch[0]].size)
114 {
115 y=now;
116 split(treap[now].ch[0],x,treap[now].ch[0],rank);
117 }
118 else
119 {
120 x=now;
121 split(treap[now].ch[1],treap[now].ch[1],y,rank-treap[treap[now].ch[0]].size-1);
122 }
123 update(now);
124 }
125 inline int merge(int x,int y)
126 {
127 down(x);down(y);
128 if(x==0 or y==0)
129 return x+y;
130 if(treap[x].rnd<treap[y].rnd)
131 {
132 treap[x].ch[1]=merge(treap[x].ch[1],y);
133 update(x);
134 update(treap[x].ch[1]);
135 return x;
136 }
137 else
138 {
139 treap[y].ch[0]=merge(x,treap[y].ch[0]);
140 update(y);
141 update(treap[y].ch[0]);
142 return y;
143 }
144 }
145 inline void remove(int pos,int num)
146 {
147 int x=0,y=0,z=0;
148 split(root,x,y,pos-1);
149 split(y,y,z,num);
150 reuse(y);
151 root=merge(x,z);
152 }
153 inline void insert(int pos,int num)
154 {
155 int x,y,z;
156 split(root,x,y,pos);
157 z=build(num);
158 root=merge(merge(x,z),y);
159 }
160 inline void make_same(int pos,int num,int c)
161 {
162 int x=0,y=0,z=0;
163 split(root,x,y,pos-1);
164 split(y,y,z,num);
165 treap[y].change=c;
166 y=merge(y,z);
167 root=merge(x,y);
168 }
169 inline void reverse(int pos,int num)
170 {
171 int x=0,y=0,z=0;
172 split(root,x,y,pos-1);
173 split(y,y,z,num);
174 treap[y].reverse^=1;
175 y=merge(y,z);
176 root=merge(x,y);
177 }
178 inline void getsum(int pos,int sum)
179 {
180 int x=0,y=0,z=0;
181 split(root,x,y,pos-1);
182 split(y,y,z,sum);
183 printf("%d\n",treap[y].sum);
184 y=merge(y,z);
185 root=merge(x,y);
186 }
187 inline void maxsum()
188 {
189 printf("%d\n",treap[root].mmax);
190 }
191 int main()
192 {
193 //scanf("%d%d",&n,&m);
194 n=read();m=read();
195 for (int i=500010;i;i--) name[++tot]=i;
196 treap[0].lmax=treap[0].rmax=treap[0].mmax=-INF;
197 root=build(n);
198 char opt[15];
199 for(int i=1;i<=m;i++)
200 {
201 char c=getchar();
202 while(c<‘A‘ or c>‘Z‘) c=getchar();
203 opt[0]=c;opt[1]=getchar();opt[2]=getchar();
204 while((c>=‘A‘ and c<=‘Z‘) or c==‘-‘) c=getchar();
205 if(opt[0]==‘I‘)
206 {
207 int k=read(),jkl=read();
208 //scanf("%d%d",&k,&jkl);
209 insert(k,jkl);
210 }
211 else if(opt[0]==‘D‘)
212 {
213 int O=read(),P=read();
214 //scanf("%d%d",&O,&P);
215 remove(O,P);
216 }
217 else if(opt[2]==‘K‘)
218 {
219 int O=read(),P=read(),C=read();
220 //scanf("%d%d%d",&O,&P,&C);
221 make_same(O,P,C);
222 }
223 else if(opt[0]==‘R‘)
224 {
225 int O=read(),P=read();
226 //scanf("%d%d",&O,&P);
227 reverse(O,P);
228 }
229 else if(opt[0]==‘G‘)
230 {
231 int O=read(),P=read();
232 //scanf("%d%d",&O,&P);
233 getsum(O,P);
234 }
235 else
236 maxsum();
237 }
238 return 0;
239 }