Time Limit: 10 Sec
Memory Limit: 64 MB
Description
请写一个程序,要求维护一个数列,支持以下 6 种操作:
请注意,格式栏 中的下划线‘ _ ’表示实际输入文件中的空格
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操作,向输出文件依次打印结果,每个答案(数字)占一行。
题目分析
Splay支持的操作几乎全在这了
甚至还要写空间回收,当然你写指针当我没说
码了两百行才完
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<queue>
using namespace std;
int read()
{
int x=0,f=1;
char ss=getchar();
while(ss<'0'||ss>'9'){if(ss=='-')f=-1;ss=getchar();}
while(ss>='0'&&ss<='9'){x=x*10+ss-'0';ss=getchar();}
return f*x;
}
const int inf=1e9;
const int maxn=1000010;
int n,m;
int a[maxn];
int fa[maxn],ch[maxn][2],size[maxn];
int val[maxn],sum[maxn],mx[maxn],lx[maxn],rx[maxn];
int sett[maxn],lzy[maxn],rt,cnt;
queue<int> q;
char ss[20];
void update(int x)
{
int lc=ch[x][0],rc=ch[x][1];
size[x]=size[lc]+size[rc]+1;
sum[x]=sum[lc]+sum[rc]+val[x];
lx[x]=max(lx[lc],sum[lc]+val[x]+lx[rc]);
rx[x]=max(rx[rc],sum[rc]+val[x]+rx[lc]);
mx[x]=max(max(mx[lc],mx[rc]),rx[lc]+lx[rc]+val[x]);
}
void push(int x)
{
int lc=ch[x][0],rc=ch[x][1];
if(sett[x])
{
int w=val[x];
sett[lc]=sett[rc]=1; val[lc]=val[rc]=w;
sum[lc]=size[lc]*w; sum[rc]=size[rc]*w;
if(w>=0){
lx[lc]=rx[lc]=mx[lc]=sum[lc];
lx[rc]=rx[rc]=mx[rc]=sum[rc];
}
else{
lx[lc]=rx[lc]=0; mx[lc]=w;
lx[rc]=rx[rc]=0; mx[rc]=w;
}
sett[x]=lzy[x]=0;
}
if(lzy[x])
{
lzy[lc]^=1; lzy[rc]^=1;
swap(lx[lc],rx[lc]); swap(lx[rc],rx[rc]);
swap(ch[lc][0],ch[lc][1]); swap(ch[rc][0],ch[rc][1]);
lzy[x]=0;
}
}
void rotate(int &p,int x)
{
int y=fa[x],z=fa[y];
int d=(ch[y][0]==x);
if(y==p) p=x;
else if(ch[z][0]==y) ch[z][0]=x;
else ch[z][1]=x;
fa[y]=x; fa[ch[x][d]]=y; fa[x]=z;
ch[y][d^1]=ch[x][d]; ch[x][d]=y;
update(y); update(x);
}
void splay(int &p,int x)
{
while(x!=p)
{
int y=fa[x],z=fa[y];
if(y!=p)
{
if((ch[z][0]==y)^(ch[y][0]==x)) rotate(p,x);
else rotate(p,y);
}
rotate(p,x);
}
}
int new_id()
{
int id=0;
if(!q.empty()) id=q.front(),q.pop();
else id=++cnt;
return id;
}
void build(int p,int ll,int rr,int pa)
{
if(ll>rr) return;
int mid=ll+rr>>1,id=new_id();
fa[id]=pa; ch[pa][mid>p]=id; val[id]=a[mid];
if(ll==rr)
{
sum[id]=mx[id]=a[mid];
lx[id]=rx[id]=max(0,a[mid]);
lzy[id]=sett[id]=0;
size[id]=1; return;
}
build(mid,ll,mid-1,id); build(mid,mid+1,rr,id);
update(id);
}
int find(int x,int k)
{
push(x);
int ss=size[ch[x][0]];
if(k==ss+1) return x;
else if(k<=ss) return find(ch[x][0],k);
else return find(ch[x][1],k-ss-1);
}
void ins()
{
int pos=read()+1,tot=read();
for(int i=1;i<=tot;++i) a[i]=read();
int x=find(rt,pos); splay(rt,x);
int y=find(rt,pos+1); splay(ch[x][1],y);
int id=0;
if(!q.empty()) id=q.front();
else id=cnt+1;
build(1+tot>>1,1,tot,0);
fa[id]=y; ch[y][0]=id;
update(y); update(x);
}
void rec(int x)
{
if(!x) return;
rec(ch[x][0]); rec(ch[x][1]);
q.push(x);
fa[x]=ch[x][0]=ch[x][1]=size[x]=val[x]=0;
lzy[x]=sett[x]=sum[x]=mx[x]=lx[x]=rx[x]=0;
}
void del()
{
int pos=read()+1,tot=read();
int x=find(rt,pos-1); splay(rt,x);
int y=find(rt,pos+tot); splay(ch[x][1],y);
int id=ch[y][0];
fa[id]=ch[y][0]=0; rec(id);
update(y); update(x);
}
int qsum()
{
int pos=read()+1,tot=read();
int x=find(rt,pos-1); splay(rt,x);
int y=find(rt,pos+tot); splay(ch[x][1],y);
return sum[ch[y][0]];
}
void rev()
{
int pos=read()+1,tot=read();
int x=find(rt,pos-1); splay(rt,x);
int y=find(rt,pos+tot); splay(ch[x][1],y);
int id=ch[y][0];
lzy[id]^=1;
swap(ch[id][0],ch[id][1]);
swap(lx[id],rx[id]);
update(y); update(x);
}
void mks()
{
int pos=read()+1,tot=read(),w=read();
int x=find(rt,pos-1); splay(rt,x);
int y=find(rt,pos+tot); splay(ch[x][1],y);
int id=ch[y][0];
val[id]=w; sett[id]=1;
sum[id]=size[id]*w;
if(w>=0) lx[id]=rx[id]=mx[id]=sum[id];
else lx[id]=rx[id]=0,mx[id]=w;
update(y); update(x);
}
int main()
{
n=read();m=read();
mx[0]=a[1]=a[n+2]=-inf;
for(int i=2;i<=n+1;++i) a[i]=read();
rt=1;
build(n+3>>1,1,n+2,0);
while(m--)
{
scanf("%s",ss);
if(ss[0]=='I') ins();
else if(ss[0]=='D') del();
else if(ss[0]=='M'&&ss[2]=='K') mks();
else if(ss[0]=='R') rev();
else if(ss[0]=='G') printf("%d\n",qsum());
else if(ss[0]=='M'&&ss[2]=='X') printf("%d\n",mx[rt]);
}
return 0;
}