#include<bits/stdc++.h> using namespace std; const int maxn=1e6+100; const int inf=1e9; int root,tot; int a[maxn]; int pos[maxn]; int rub[maxn]; int top; int n,m; struct Splay_tree { int ch[2];//左右儿子 int size;//子树大小 int fa;//父亲 int tag;//赋值标记 int v;//权值 int rev;//翻转标记 int sum;//区间权值和 int left;//左区间,指区间最大前缀和 int right;//右区间,指区间最大后缀和 int middle;//中区间,指区间最大字段和 void clear () { ch[0]=ch[1]=fa=rev=tag=0; } }t[maxn]; int rubish () { //垃圾回收 if (top==0) return ++tot; int tt=rub[top--]; return tt; } void change_val (int id,int v) { //更新点值 if (!id) return; t[id].tag=t[id].v=v;//打标记 t[id].sum=v*t[id].size;//更新区间权值和 t[id].left=t[id].right=max(t[id].sum,0);//左右区间更新 t[id].middle=max(t[id].sum,v);//最大字段和更新 } void change_rev (int id) { //更新翻转 swap(t[id].ch[0],t[id].ch[1]);//交换左右儿子 swap(t[id].left,t[id].right);//交换左右区间 t[id].rev^=1; //打翻转标记 } void pushup (int id) { //信息更新 Splay_tree &x=t[t[id].ch[0]]; Splay_tree &y=t[t[id].ch[1]]; int v=t[id].v; Splay_tree &wjm=t[id]; wjm.sum=x.sum+y.sum+v; wjm.size=x.size+y.size+1; wjm.middle=max(max(x.middle,y.middle),x.right+y.left+v); wjm.left=max(x.left,x.sum+y.left+v); wjm.right=max(y.right,y.sum+x.right+v); } void pushdown (int id) { //标记下传 if (t[id].tag!=inf) { change_val(t[id].ch[0],t[id].tag); change_val(t[id].ch[1],t[id].tag); t[id].tag=inf; } if (t[id].rev) { change_rev(t[id].ch[0]); change_rev(t[id].ch[1]); t[id].rev=0; } } void rotate (int x) { int y=t[x].fa; int z=t[y].fa; int k=(t[y].ch[1]==x); t[z].ch[t[z].ch[1]==y]=x; t[x].fa=z; t[y].ch[k]=t[x].ch[k^1]; t[t[x].ch[k^1]].fa=y; t[x].ch[k^1]=y; t[y].fa=x; pushup(y); pushup(x); } void splay (int x,int s) { while (t[x].fa!=s) { int y=t[x].fa; int z=t[y].fa; if (z!=s) (t[z].ch[0]==y)^(t[y].ch[0]==x)?rotate(x):rotate(y); rotate(x); } if (s==0) root=x; } void newNode (int id,int x) { t[id].middle=t[id].sum=x; t[id].tag=inf; t[id].rev=0; t[id].left=t[id].right=max(x,0); t[id].size=1; } void build (int l,int r,int fa) { //建树 int mid=(l+r)>>1; int id=pos[mid]; int pre=pos[fa]; if (l==r) newNode(id,a[l]); if (l<mid) build(l,mid-1,mid); if (r>mid) build(mid+1,r,mid); t[id].v=a[mid]; t[id].fa=pre; t[id].tag=inf; pushup(id); t[pre].ch[mid>=fa]=id; } int kth (int x) { int id=root; while (1) { pushdown(id); if (t[t[id].ch[0]].size>=x) id=t[id].ch[0]; else if (t[t[id].ch[0]].size+1==x) return id; else x-=t[t[id].ch[0]].size+1,id=t[id].ch[1]; } } void remove (int id) { //删除一个子树 if (t[id].ch[0]) remove(t[id].ch[0]); if (t[id].ch[1]) remove(t[id].ch[1]); rub[++top]=id; t[id].clear(); } int split (int k,int len) { //到目标区间的位置 int x=kth(k); int y=kth(k+len+1); splay(x,0); splay(y,x); return t[y].ch[0]; } void query (int x,int len) { //查询区间权值和 int id=split(x,len);//先找到该区间 printf("%d ",t[id].sum); } void update (int x,int len,int v) { //更新区间的值 int id=split(x,len); int y=t[id].fa; change_val(id,v); pushup(y); pushup(t[y].fa); } void reverse (int x,int len) { //翻转区间 int id=split(x,len); int y=t[id].fa; if (t[id].tag!=inf) return; change_rev(id);//翻转该区间 pushup(y); pushup(t[y].fa); } void del (int x,int len) { //删除区间 int id=split(x,len); int y=t[id].fa; remove(id); t[y].ch[0]=0; pushup(y); pushup(t[y].fa); } void ins (int k,int len) { //插入区间 for (int i=1;i<=len;i++) scanf("%d",&a[i]); for (int i=1;i<=len;i++) pos[i]=rubish(); build(1,len,0);//将输入的区间建一颗树 int p=pos[(1+len)>>1]; int x=kth(k+1); int y=kth(k+2);//找到插入的位置 splay(x,0); splay(y,x); t[p].fa=y; t[y].ch[0]=p; pushup(y); pushup(x); } int main () { scanf("%d%d",&n,&m); t[0].middle=a[1]=a[n+2]=-inf; for (int i=1;i<=n;i++) scanf("%d",&a[i+1]); for (int i=1;i<=n+2;i++) pos[i]=i; build(1,n+2,0);//建一颗树 root=(n+3)>>1; tot=n+2; for (int i=1;i<=m;i++) { string s; int x,y,len; cin>>s; if (s!="MAX-SUM") scanf("%d%d",&x,&len); else printf("%d ",t[root].middle); if (s=="INSERT") ins(x,len);//从x开始插入一个长度为len区间 if (s=="DELETE") del(x,len);//从x开始删除一个长度为len的区间 if (s=="MAKE-SAME") scanf("%d",&y),update(x,len,y);//从x开始把长度为len的区间连续修改成y if (s=="REVERSE") reverse(x,len);//翻转从x开始长度为len的区间 if (s=="GET-SUM") query(x,len);//查询从x开始长度为len的区间和 } }