#include <cstdio> #include <cstring> #include <iostream> #include <algorithm> #include <set> #include <map> #include <queue> #include <cstdlib> #include <cctype> #include <cmath> #include <iomanip> using namespace std; #define ll long long #define keyTree (son[son[rt][1]][0]) static const int M = 500000 + 5; static const int INF = 700000000; struct SplayTree{ int fa[M],son[M][2],sz[M]; int val[M],sum[M]; int L_max[M],R_max[M],sum_max[M]; bool lazy_rev[M]; int lazy_num[M]; int tot,rt; int rub[M],top; SplayTree(){ tot=rt=0; L_max[0]=R_max[0]=sum_max[0]=-INF; top=0; for(int i=1;i<M;++i)rub[++top]=M-i; Newnode(rt,0,-INF); Newnode(son[rt][1],rt,-INF); Up(rt); } void Newnode(int &u,int f,int x){ u=rub[top--]; ++tot; fa[u]=f; son[u][0]=son[u][1]=0; sz[u]=1; val[u]=sum[u]=x; L_max[u]=R_max[u]=sum_max[u]=x; lazy_rev[u]=false; lazy_num[u]=INF; } void Rotate(int p){ int F=fa[p]; int d=son[F][1]==p; son[F][d]=son[p][!d]; if(son[p][!d])fa[son[p][!d]]=F; fa[p]=fa[F]; son[fa[p]][son[fa[p]][1]==F]=p; fa[F]=p; son[p][!d]=F; Up(F); } void Splay(int p,int goal){ Down from Root to P */ while(fa[p]!=goal){ int F=fa[p]; if(fa[F]!=goal){ if(son[F][1]==p^son[fa[F]][1]==F)Rotate(p); else Rotate(F); } Rotate(p); } Up(p); if(!goal)rt=p; } void RotateTo(int k,int goal){ int p=Find(k); Splay(p,goal); } void Rev(int p){ lazy_rev[p]^=true; int t=son[p][0]; son[p][0]=son[p][1]; son[p][1]=t; t=L_max[p]; L_max[p]=R_max[p]; R_max[p]=t; } void Clr(int p,int c){ val[p]=c; sum[p]=sz[p]*c; lazy_num[p]=c; sum_max[p]=L_max[p]=R_max[p]=max(c,sum[p]); } void Up(int p){ sz[p]=1+sz[son[p][0]]+sz[son[p][1]]; sum[p]=val[p]+sum[son[p][0]]+sum[son[p][1]]; sum_max[p]=max(sum_max[son[p][0]],sum_max[son[p][1]]); L_max[p]=max(L_max[son[p][0]],sum[son[p][0]]+val[p]+max(0,L_max[son[p][1]])); R_max[p]=max(R_max[son[p][1]],sum[son[p][1]]+val[p]+max(0,R_max[son[p][0]])); sum_max[p]=max(sum_max[p],val[p]+max(0,R_max[son[p][0]])+max(0,L_max[son[p][1]])); } void Down(int p){ if(lazy_rev[p]){ if(son[p][0])Rev(son[p][0]); if(son[p][1])Rev(son[p][1]); lazy_rev[p]=false; } if(lazy_num[p]<=1000){ if(son[p][0])Clr(son[p][0],lazy_num[p]); if(son[p][1])Clr(son[p][1],lazy_num[p]); lazy_num[p]=INF; } } int Find(int k){ int p=rt;Down(p); while(sz[son[p][0]]!=k){ if(sz[son[p][0]]>k)p=son[p][0]; else{ k-=sz[son[p][0]]+1; p=son[p][1]; } Down(p); } return p; } void build(int &u,int f,int L,int R,int num[]){ int mid=L+R>>1; Newnode(u,f,num[mid]); if(L<mid)build(son[u][0],u,L,mid-1,num); if(mid<R)build(son[u][1],u,mid+1,R,num); Up(u); } void Insert(int L,int len,int num[]){ RotateTo(L,0); RotateTo(L+1,rt); build(keyTree,son[rt][1],1,len,num); Up(son[rt][1]); Up(rt); } void recur(int p){ rub[++top]=p; --tot; if(son[p][0])recur(son[p][0]); if(son[p][1])recur(son[p][1]); } void Del(int L,int len){ int R=L+len-1; RotateTo(L-1,0); RotateTo(R+1,rt); recur(keyTree); son[son[rt][1]][0]=0; Up(son[rt][1]); Up(rt); } void Fill(int L,int len, int x){ RotateTo(L-1,0); RotateTo(L+len,rt); Clr(keyTree,x); Up(son[rt][1]); Up(rt); } void Reverse(int L,int len){ RotateTo(L-1,0); RotateTo(L+len,rt); Rev(keyTree); Up(son[rt][1]); Up(rt); } void Get_sum(int L,int len){ RotateTo(L-1,0); RotateTo(L+len,rt); printf("%d\n",sum[keyTree]); } void Max_sum(){ printf("%d\n",sum_max[rt]); } void debug(int p){ printf("v: %d , sz: %d , val: %d , sum: %d , lazy_rev: %d , lazy_sum: %d , L_max[p]: %d , R_max[p]: %d , sum_max: %d\n" ,p,sz[p],val[p],sum[p],lazy_rev[p],lazy_num[p],L_max[p],R_max[p],sum_max[p]); printf("%d %d\n",son[p][0],son[p][1]); Down(p); if(son[p][0])debug(son[p][0]); if(son[p][1])debug(son[p][1]); } }Tree; int A[M]; char str[50]; int main(){ int n,m; scanf("%d%d",&n,&m); for(int i=1;i<=n;++i)scanf("%d",&A[i]); Tree.Insert(0,n,A); while(m--){ scanf("%s",str); int pos,len,c; if(str[0]=='I'){ scanf("%d%d",&pos,&len); for(int i=1;i<=len;++i)scanf("%d",&A[i]); Tree.Insert(pos,len,A); }else if(str[0]=='D'){ scanf("%d%d",&pos,&len); Tree.Del(pos,len); }else if(str[0]=='R'){ scanf("%d%d",&pos,&len); Tree.Reverse(pos,len); }else if(str[0]=='G'){ scanf("%d%d",&pos,&len); Tree.Get_sum(pos,len); }else if(str[0]=='M'&&str[2]=='K'){ scanf("%d%d%d",&pos,&len,&c); Tree.Fill(pos,len,c); }else{ Tree.Max_sum(); } } return 0; }
|