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;
}