Description
Input
輸入的第1 行包含兩個數N 和M(M ≤20 000),N 表示初始時數列中數的個數,M表示要進行的操作數目。
第2行包含N個數字,描述初始時的數列。
以下M行,每行一條命令,格式參見問題描述中的表格。
任何時刻數列中最多含有500 000個數,數列中任何一個數字均在[-1 000, 1 000]內。
插入的數字總數不超過4 000 000個,輸入文件大小不超過20MBytes。
Output
對於輸入數據中的GET-SUM和MAX-SUM操作,向輸出文件依次打印結果,每個答案(數字)佔一行。
Sample Input
9 8
2 -6 3 5 1 -5 -3 6 3
GET-SUM 5 4
MAX-SUM
INSERT 8 3 -5 7 2
DELETE 12 1
MAKE-SAME 3 3 2
REVERSE 3 6
GET-SUM 5 4
MAX-SUM
Sample Output
-1
10
1
10
HINT
Solution
開4000000的數組顯然會炸,需要手動回收內存
注意當所有數都是負數的時候maxsum不能一個都不取…
QvQ
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<queue>
#define MAXN 1000010
#define INF 0x3f3f3f3f
#define Max(a,b) (a>b?a:b)
#define lc t[x].ch[0]
#define rc t[x].ch[1]
using namespace std;
int n,m,root,siz=0;
queue<int>q;
struct Node{
int val,ch[2],father,siz,rev,lazy,sum,lsum,rsum,maxsum;
Node(){ch[0]=ch[1]=val=father=rev=siz=lazy=sum=lsum=rsum=maxsum=0;}
}t[MAXN];
int num[MAXN];
inline int read()
{
int f=1,x=0;char c=getchar();
while(c<'0'||c>'9'){
if(c=='-')f=-1;c=getchar();
}
while(c>='0'&&c<='9'){
x=x*10+c-'0';c=getchar();
}
return x*f;
}
inline void exchange(int x)
{
swap(lc,rc);
swap(t[x].lsum,t[x].rsum);
}
inline void Update(int x)
{
if(!x)return;
t[x].siz=t[lc].siz+t[rc].siz+1;
t[x].sum=t[lc].sum+t[rc].sum+t[x].val;
t[x].maxsum=t[lc].rsum+t[x].val+t[rc].lsum;
if(lc)t[x].maxsum=Max(t[x].maxsum,t[lc].maxsum);
if(rc)t[x].maxsum=Max(t[x].maxsum,t[rc].maxsum);
t[x].lsum=Max(t[lc].lsum,t[lc].sum+t[x].val+t[rc].lsum);
t[x].rsum=Max(t[rc].rsum,t[rc].sum+t[x].val+t[lc].rsum);
}
inline void Recycle(int x)
{
if(!x)return;
Recycle(lc);Recycle(rc);
t[x]=Node();q.push(x);
}
inline void Pushdown(int x)
{
if(!x)return;
if(t[x].rev)
{
t[x].rev=0;
t[lc].rev^=1;t[rc].rev^=1;
exchange(lc);exchange(rc);
}
if(t[x].lazy)
{
t[x].lazy=0;
if(lc)
{
t[lc].val=t[x].val;
t[lc].lazy=1;
t[lc].lsum=t[lc].rsum=Max(0,t[lc].siz*t[x].val);
t[lc].maxsum=Max(t[x].val,t[lc].siz*t[x].val);
t[lc].sum=t[lc].siz*t[x].val;
}
if(rc)
{
t[rc].val=t[x].val;
t[rc].lazy=1;
t[rc].lsum=t[rc].rsum=Max(0,t[rc].siz*t[x].val);
t[rc].maxsum=Max(t[x].val,t[rc].siz*t[x].val);
t[rc].sum=t[rc].siz*t[x].val;
}
}
}
inline void Rotate(int x,int &k)
{
int y=t[x].father;
int z=t[y].father;
int p=(t[y].ch[0]==x)?0:1;
if(y==k)k=x;
else
{
if(t[z].ch[0]==y)t[z].ch[0]=x;
else t[z].ch[1]=x;
}
t[x].father=z;
t[y].ch[p]=t[x].ch[p^1];
t[t[x].ch[p^1]].father=y;
t[x].ch[p^1]=y;
t[y].father=x;
Update(y),Update(x);
}
inline void Splay(int x,int &k)
{
while(x!=k)
{
int y=t[x].father;
int z=t[y].father;
if(y!=k)
{
if((t[y].ch[0]==x)^(t[z].ch[0]==y))
Rotate(x,k);
else Rotate(y,k);
}
Rotate(x,k);
}
}
inline int Build(int l,int r,int f)
{
if(r<l)return 0;
int now=q.front();q.pop();
int mid=(l+r)/2;
t[now].val=num[mid];
t[now].father=f;
if(l==r)
{
t[now].lsum=t[now].rsum=Max(0,t[now].val);
t[now].maxsum=t[now].sum=t[now].val;
t[now].siz=1;return now;;
}
t[now].ch[0]=Build(l,mid-1,now);
t[now].ch[1]=Build(mid+1,r,now);
Update(now);
return now;
}
inline int Find(int x,int k)
{
if(!x)return 0;
Pushdown(x);
if(k<=t[lc].siz)return Find(lc,k);
if(k>t[lc].siz+1)return Find(rc,k-t[lc].siz-1);
return x;
}
int main()
{
for(int i=1;i<MAXN;i++)q.push(i);
n=read();m=read();
for(int i=1;i<=n;i++)
num[i+1]=read();
num[1]=num[n+2]=-INF;
root=Build(1,n+2,0);
for(int i=1;i<=m;i++)
{
char opt[15];
int pos,tot,c,x,y,R,p;
scanf("%s",opt);
switch(opt[0])
{
case 'I':
pos=read();tot=read();
for(int i=1;i<=tot;i++)
num[i]=read();
x=Find(root,pos+1);
y=Find(root,pos+2);
Splay(x,root);Splay(y,t[root].ch[1]);
R=Build(1,tot,y);
t[y].ch[0]=R;
Update(y);Update(x);
break;
case 'D':
pos=read();tot=read();
x=Find(root,pos);
y=Find(root,pos+tot+1);
Splay(x,root);Splay(y,t[root].ch[1]);
Recycle(t[y].ch[0]);
t[y].ch[0]=0;
Update(y);Update(x);
break;
case 'M':
if(opt[2]=='K')
{
pos=read();tot=read();c=read();
x=Find(root,pos);
y=Find(root,pos+tot+1);
Splay(x,root);Splay(y,t[root].ch[1]);
p=t[y].ch[0];
t[p].rev=0;t[p].lazy=1;t[p].val=c;
t[p].lsum=t[p].rsum=Max(0,c*t[p].siz);
t[p].maxsum=t[p].sum=c*t[p].siz;
Update(y);Update(x);
}
else if(opt[2]=='X')
printf("%d\n",t[root].maxsum);
break;
case 'R':
pos=read();tot=read();
x=Find(root,pos);
y=Find(root,pos+tot+1);
Splay(x,root);Splay(y,t[root].ch[1]);
p=t[y].ch[0];
if(!t[p].lazy){
t[p].rev^=1;
exchange(p);
Update(y);Update(x);
}
break;
case 'G':
pos=read();tot=read();
x=Find(root,pos);
y=Find(root,pos+tot+1);
Splay(x,root);Splay(y,t[root].ch[1]);
p=t[y].ch[0];
printf("%d\n",t[p].sum);
break;
}
}
return 0;
}