Splay终极模板。。注意细节。还是好不熟练哦。
【代码】
#include <cstdio>
#include <iostream>
#include <queue>
#include <vector>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <stack>
#define N 1000005
#define M 200005
#define INF 1e9
#define mod 1000000
using namespace std;
typedef long long ll;
typedef pair<ll,ll> pa;
int read()
{
int x=0,f=1;char ch=getchar();
while(!isdigit(ch)){if(ch=='-') f=-1;ch=getchar();}
while(isdigit(ch)){x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}
return x*f;
}
int n,rt,cnt,ans,m;
int son[N][2],fa[N],sz[N],num[N],pos[N],id[N];
int sum[N],mx[N],lx[N],rx[N],a[N];
bool rev[N],tag[N];
queue<int>q;
void pushup(int k)
{
int l=son[k][0],r=son[k][1];
sum[k]=sum[l]+sum[r]+num[k];
sz[k]=sz[l]+sz[r]+1;
mx[k]=max(max(mx[l],mx[r]),rx[l]+num[k]+lx[r]);
lx[k]=max(lx[l],sum[l]+lx[r]+num[k]);
rx[k]=max(rx[r],sum[r]+rx[l]+num[k]);
}
void pushdown(int k)
{
int l=son[k][0],r=son[k][1];
if(tag[k])
{
rev[k]=tag[k]=0;
if(l) tag[l]=1,num[l]=num[k],sum[l]=num[l]*sz[l];
if(r) tag[r]=1,num[r]=num[k],sum[r]=num[r]*sz[r];
if(num[k]>=0)
{
if(l) mx[l]=lx[l]=rx[l]=sum[l];
if(r) mx[r]=lx[r]=rx[r]=sum[r];
}
else
{
if(l) lx[l]=rx[l]=0,mx[l]=num[k];
if(r) lx[r]=rx[r]=0,mx[r]=num[k];
}
}
if(rev[k])
{
rev[k]=0;rev[l]^=1,rev[r]^=1;
swap(lx[l],rx[l]),swap(lx[r],rx[r]);
swap(son[l][0],son[l][1]);swap(son[r][0],son[r][1]);
}
}
void Rotate(int x,int &k)
{
int y=fa[x],z=fa[y],l,r;
l=son[y][1]==x;r=l^1;
if(y==k) k=x;
else son[z][son[z][1]==y]=x;
fa[x]=z;fa[y]=x;fa[son[x][r]]=y;
son[y][l]=son[x][r];son[x][r]=y;
pushup(y);pushup(x);
}
void Splay(int x,int &k)
{
while(x!=k)
{
int y=fa[x],z=fa[y];
if(y!=k) {
if(son[z][0]==y^son[y][0]==x) Rotate(x,k);
else Rotate(y,k);
}
Rotate(x,k);
}
}
int Find(int k,int x)
{
pushdown(k);
int l=son[k][0],r=son[k][1];
if(sz[l]+1==x) return k;
if(sz[l]+1>x) return Find(l,x);
return Find(r,x-sz[l]-1);
}
int Spilt(int k,int tot)
{
int x=Find(rt,k),y=Find(rt,k+tot+1);
Splay(x,rt);
Splay(y,son[x][1]);
return son[y][0];
}
void Build(int l,int r,int f)
{
if(l>r) return;
int mid=l+r>>1;int now=id[mid],Last=id[f];
if(l==r)
{
sum[now]=a[l],sz[now]=1;
tag[now]=rev[now]=0;
if(a[l]>=0) lx[now]=rx[now]=mx[now]=a[l];
else lx[now]=rx[now]=0,mx[now]=a[l];
}
else Build(l,mid-1,mid),Build(mid+1,r,mid);
num[now]=a[mid];fa[now]=Last;pushup(now);
son[Last][mid>f]=now;
}
void Insert(int k,int tot)
{
for(int i=1;i<=tot;i++) a[i]=read();
for(int i=1;i<=tot;i++) if(!q.empty()) id[i]=q.front(),q.pop();
else id[i]=++cnt;
Build(1,tot,0);int z=id[1+tot>>1];
int x=Find(rt,k+1),y=Find(rt,k+2);
Splay(x,rt);Splay(y,son[x][1]);
fa[z]=y;son[y][0]=z;
pushup(y);pushup(x);
}
void Change(int k,int tot,int w)
{
int x=Spilt(k,tot),y=fa[x];
num[x]=w;tag[x]=1;sum[x]=sz[x]*w;
if(w>=0) lx[x]=rx[x]=mx[x]=sum[x];
else lx[x]=rx[x]=0,mx[x]=w;
pushup(y);pushup(fa[y]);
}
void Reverse(int k,int tot)
{
int x=Spilt(k,tot),y=fa[x];
if(!tag[x])
{
rev[x]^=1;
swap(son[x][0],son[x][1]);
swap(lx[x],rx[x]);pushup(y);pushup(fa[y]);
}
}
void Del(int k)
{
if(!k) return;
int l=son[k][0],r=son[k][1];
Del(l);Del(r);q.push(k);
fa[k]=son[k][0]=son[k][1]=0;
tag[k]=rev[k]=0;
}
void Delete(int k,int tot)
{
int x=Spilt(k,tot),y=fa[x];
Del(x);son[y][0]=0;
pushup(y);pushup(fa[y]);
}
void Query(int k,int tot)
{
int x=Spilt(k,tot);
printf("%d\n",sum[x]);
}
void Solve()
{
while(m--)
{
char ch[10];static int x,y;
scanf("%s",ch);
if(ch[0]=='M'&&ch[2]=='X')
printf("%d\n",mx[rt]);
else
{
x=read(),y=read();
if(ch[0]=='I') Insert(x,y);
else if(ch[0]=='D') Delete(x,y);
else if(ch[0]=='M') Change(x,y,read());
else if(ch[0]=='R') Reverse(x,y);
else Query(x,y);
}
}
}
int main()
{
n=read();m=read();
mx[0]=a[1]=a[n+2]=-INF;
for(int i=1;i<=n;i++) a[i+1]=read();
for(int i=1;i<=n+2;i++) id[i]=i;
Build(1,n+2,0);rt=n+3>>1;cnt=n+2;
Solve();
return 0;
}