传说中的splay tree模版题之完全体?
代码写的弱。。。跑的慢。。。据说区间操作其实不需要分裂?
有时间再优化一下吧。。。。
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
const int maxn=500010;
const int inf=500000000;
int root;
int a[maxn],siz[maxn],lm[maxn],rm[maxn],s[2][maxn],sum[maxn],v[maxn],mx[maxn],n,m,stk[maxn],t;
bool sflag[maxn],flag[maxn];
char S[20];
int cmp(int ro,int k){
if (siz[s[0][ro]]+1==k) return -1;
return k<siz[s[0][ro]]+1?0:1;
}
void maintain(int now){
lm[now]=max(lm[s[0][now]],sum[s[0][now]]+v[now]+lm[s[1][now]]);
rm[now]=max(rm[s[1][now]],sum[s[1][now]]+v[now]+rm[s[0][now]]);
mx[now]=max(rm[s[0][now]]+v[now]+lm[s[1][now]],max(mx[s[0][now]],mx[s[1][now]]));
sum[now]=sum[s[0][now]]+sum[s[1][now]]+v[now];
siz[now]=siz[s[0][now]]+siz[s[1][now]]+1;
}
void change(int ro,int samev){
sflag[ro]=1;
v[ro]=samev;
sum[ro]=samev*siz[ro];
lm[ro]=rm[ro]=max(sum[ro],0);
mx[ro]=max(sum[ro],v[ro]);
}
void pushdown(int ro){
if (sflag[ro]){
if (s[0][ro]) change(s[0][ro],v[ro]);
if (s[1][ro]) change(s[1][ro],v[ro]);
sflag[ro]=0;
}
if (flag[ro]){
swap(s[0][ro],s[1][ro]);
if (s[0][ro]){
flag[s[0][ro]]^=1;
swap(lm[s[0][ro]],rm[s[0][ro]]);
}
if (s[1][ro]){
flag[s[1][ro]]^=1;
swap(lm[s[1][ro]],rm[s[1][ro]]);
}
flag[ro]=0;
}
}
void rotate(int &ro,int d){
int tmp=s[d^1][ro];
pushdown(ro);pushdown(tmp);
s[d^1][ro]=s[d][tmp];
s[d][tmp]=ro;
maintain(ro);maintain(tmp);
ro=tmp;
}
void splay_kth(int &ro,int k){
pushdown(ro);
int d1=cmp(ro,k);
if (d1==1) k-=siz[s[0][ro]]+1;
if (d1!=-1){
int p=s[d1][ro];
pushdown(p);
int d2=cmp(p,k);
if (d2!=-1){
int k2=(d2==0)?k:k-siz[s[0][p]]-1;
splay_kth(s[d2][p],k2);
if (d1==d2) rotate(ro,d1^1);
else rotate(s[d1][ro],d1);
}
rotate(ro,d1^1);
}
}
void split (int ro,int len,int &le,int &ri){
splay_kth(ro,len);
le=ro;ri=s[1][ro];s[1][ro]=0;
maintain(le);maintain(ri);
}
int merge(int le,int ri){
splay_kth(le,siz[le]);
s[1][le]=ri;
maintain(le);
return le;
}
int build(int l,int r){
if (l==r){
int now=stk[t--];
mx[now]=sum[now]=a[l];
lm[now]=rm[now]=max(0,a[l]);
s[0][now]=s[1][now]=0;
sflag[now]=flag[now]=0;
v[now]=a[l];
siz[now]=1;
return now;
}
int now=stk[t--];
int mid=(l+r)>>1;
if (l<mid) s[0][now]=build(l,mid-1);
else s[0][now]=0;
s[1][now]=build(mid+1,r);
sflag[now]=flag[now]=0;
v[now]=a[mid];
maintain(now);
return now;
}
void insert(int pos,int n){
int ro1=build(1,n);
int ro2=0;
split(root,pos+1,root,ro2);
root=merge(merge(root,ro1),ro2);
}
void recycle(int ro){
stk[++t]=ro;
if (s[0][ro])recycle(s[0][ro]);
if (s[1][ro])recycle(s[1][ro]);
return ;
}
void del(int pos,int n){
int ro1,ro2;
ro1=ro2=0;
split(root,pos,root,ro1);
split(ro1,n,ro1,ro2);
recycle(ro1);
root=merge(root,ro2);
}
void samev(int pos,int n,int samev){
int ro1,ro2;
ro1=ro2=0;
split(root,pos,root,ro1);
split(ro1,n,ro1,ro2);
change(ro1,samev);
root=merge(root,merge(ro1,ro2));
}
void reverse(int pos,int n){
int ro1,ro2;
ro1=ro2=0;
split(root,pos,root,ro1);
split(ro1,n,ro1,ro2);
flag[ro1]^=1;
swap(lm[ro1],rm[ro1]);
root=merge(root,merge(ro1,ro2));
}
void get_sum(int pos,int n){
int ro1,ro2;
ro1=ro2=0;
split(root,pos,root,ro1);
split(ro1,n,ro1,ro2);
printf("%d\n",sum[ro1]);
root=merge(root,merge(ro1,ro2));
}
int main(){
#ifndef ONLINE_JUDGE
freopen("sequence.in","r",stdin);
freopen("sequence.out","w",stdout);
#endif
for (int i=500000;i>=1;i--) stk[++t]=i;
scanf("%d%d",&n,&m);
for (int i=1;i<=n;i++) scanf("%d",&a[i]);
a[0]=-inf;n++;a[n]=-inf;
lm[0]=rm[0]=0;mx[0]=-inf;
sum[0]=v[0]=siz[0]=0;
root=build(0,n);
for (int i=1;i<=m;i++){
scanf("%s",&S);
int pos,c;
switch(S[2]){
case 'S': //INSERT_posi_tot_ci
scanf("%d%d",&pos,&n);
if (n<=0) break;
for (int i=1;i<=n;i++) scanf("%d",&a[i]);
insert(pos,n);
break;
case 'L': //DELETE_posi_tot
scanf("%d%d",&pos,&n);
if (n<=0) break;
del(pos,n);
break;
case 'K': //MAKE-SAME_posi_tot_c
scanf("%d%d%d",&pos,&n,&c);
if (n<=0) break;
samev(pos,n,c);
break;
case 'V': //REVERSE_posi_tot
scanf("%d%d",&pos,&n);
if (n<=0) break;
reverse(pos,n);
break;
case 'T': //GET-SUM_posi_tot
scanf("%d%d",&pos,&n);
if (n<=0){
printf("0\n");
break;
}
get_sum(pos,n);
break;
case 'X': //MAX-SUM
printf("%d\n",mx[root]);
break;
}
}
}