传送门:bzoj1500
题解
splay模板题,推荐一篇题解。
一些注意事项:
1.t[0].mx=v[1]=v[n+2]=-inf
,在
p
u
s
h
u
p
pushup
pushup时会和子节点的
m
x
mx
mx取
m
a
x
max
max,最后答案可能为负,所以要设为
−
i
n
f
-inf
−inf。
2.st=inf
,赋值标记要初始化为一个不在值域范围
[
−
1000
,
1000
]
[-1000,1000]
[−1000,1000]内的数
3.pushup(y);pushup(x);
每次操作完记得
p
u
s
h
u
p
pushup
pushup
4.数据点数过多,需要存内存池动态维护标号。
代码
#include<bits/stdc++.h>
using namespace std;
const int N=5e5+10;
int n,m,v[N];
char cmmd[50],cc;
char cp;
inline void rd(int &x)
{
cp=getchar();x=0;int f=0;
for(;!isdigit(cp);cp=getchar()) if(cp=='-') f=1;
for(;isdigit(cp);cp=getchar()) x=(x<<3)+(x<<1)+(cp^48);
if(f) x=-x;
}
namespace BST{
#define lc(x) t[(x)].ch[0]
#define rc(x) t[(x)].ch[1]
#define F(x) t[(x)].fa
int rt,stk[N],top;
struct node{
int ch[2],fa,rv,st,sz;
int lx,rx,mx,sum,val;
inline void itia(){ch[0]=ch[1]=fa=rv=0;}
inline void mk(int x){lx=rx=mx=sum=val=x;st=N;sz=1;}
inline void cg(int x){val=st=x;sum=sz*x;mx=max(x,sum);lx=rx=max(0,sum);}
inline void rev(){rv^=1;swap(ch[0],ch[1]);swap(lx,rx);}
}t[N];
struct pol{
int cnt,q[N],top;
inline void psh(int x){q[++top]=x;t[x].itia();}
inline int nw(){if(top) return q[top--];return ++cnt;}
}pl;
inline void pushdown(int x)
{
if(t[x].st!=N){
if(lc(x)) t[lc(x)].cg(t[x].st);
if(rc(x)) t[rc(x)].cg(t[x].st);
t[x].st=N;
}
if(t[x].rv){
if(lc(x)) t[lc(x)].rev();
if(rc(x)) t[rc(x)].rev();
t[x].rv=0;
}
}
inline void pushup(int x)
{
int l=lc(x),r=rc(x);
t[x].sz=t[l].sz+t[r].sz+1;
t[x].sum=t[l].sum+t[r].sum+t[x].val;
t[x].mx=max(max(t[l].mx,t[r].mx),t[l].rx+t[x].val+t[r].lx);
t[x].lx=max(t[l].lx,t[l].sum+t[x].val+t[r].lx);
t[x].rx=max(t[r].rx,t[r].sum+t[x].val+t[l].rx);
}
inline void rot(int x)
{
int y=F(x),z=F(y),dr=(rc(y)==x);
t[y].ch[dr]=t[x].ch[dr^1];if(t[y].ch[dr]) F(t[y].ch[dr])=y;
F(x)=z;if(z) t[z].ch[(rc(z)==y)]=x;
F(y)=x;t[x].ch[dr^1]=y;pushup(y);
}
inline void splay(int x,int gl)
{
int y,z;top=0;
for(y=x;y;y=F(y)) stk[++top]=y;
for(;top;--top) pushdown(stk[top]);
if(F(x)==gl) return;if(!gl) rt=x;
for(;F(x)!=gl;rot(x)){
y=F(x);z=F(y);
if(z!=gl) ((rc(y)==x)^(rc(z)==y))?rot(x):rot(y);
}
pushup(x);if(F(x)) pushup(F(x));
}
inline int kth(int x)
{
for(int u=rt,re;;){
pushdown(u);re=t[lc(u)].sz+1;
if(x==re) return u;
if(x<re) u=lc(u);else x-=re,u=rc(u);
}
}
int build(int l,int r)
{
if(l>r) return 0;
int x=pl.nw(),mid=(l+r)>>1;t[x].mk(v[mid]);
lc(x)=build(l,mid-1);rc(x)=build(mid+1,r);
F(lc(x))=F(rc(x))=x;pushup(x);return x;
}
inline void ins()
{
int i,x,y,cur;
rd(x);rd(y);
for(i=1;i<=y;++i) rd(v[i]);
cur=build(1,y);y=kth(x+2);x=kth(x+1);
splay(x,0);splay(y,rt);
lc(y)=cur;F(cur)=y;
pushup(y);pushup(x);
}
void del(int x){if(lc(x)) del(lc(x));if(rc(x)) del(rc(x));pl.psh(x);}
}
int main(){
using namespace BST;
int i,x,y,z;
rd(n);rd(m);
t[0].mx=v[1]=v[n+2]=-1e9;
for(i=2;i<=n+1;++i) rd(v[i]);
rt=build(1,n+2);
for(;m;--m){
scanf("%s",cmmd);cc=cmmd[0];
if(cc=='M' && cmmd[2]=='X') printf("%d\n",t[rt].mx);
else if(cc=='I') ins();
else{
rd(x);rd(y);
y=kth(x+y+1);x=kth(x);
splay(x,0);
splay(y,rt);
if(cc=='D') {F(lc(y))=0;del(lc(y));lc(y)=0;}
else if(cc=='M'){rd(z);t[lc(y)].cg(z);}
else if(cc=='R') t[lc(y)].rev();
else printf("%d\n",t[lc(y)].sum);
pushup(y);pushup(x);
}
}
return 0;
}