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 }