BZOJ 1500, 维修数列
2016-09-11 15:51
309 查看
Problem
传送门Mean
编写一个支持插入、删除、修改、翻转、求和以及求和最大子序列的数据结构。Analysis
Splay无疑。但是写太丑也是会TLE的,比方说插入的时候应该以建树的形式插入,而不是一个点一个点的形式。
实现起来要注意的细节很多,对练习打Splay挺有好处。
(陆陆续续调试了好多天,总算在崩溃之前AC了……)
Code
#include<cstdio> const int N=500005; int n,m,o,cnt,top,p,t,c,a ,f ,son [2],val ,sz ,sum ,pre ,suf ,mx ={-1000},rec ; bool rev ,tag ; char op[15]; int max(int a,int b){return a>b?a:b;} void swap(int &a,int &b){int t=a;a=b;b=t;} void revl(int x){if(!x) return;swap(son[x][0],son[x][1]),swap(pre[x],suf[x]);rev[x]^=1;} void same(int x,int v){if(!x) return;val[x]=v;sum[x]=sz[x]*v;mx[x]=pre[x]=suf[x]=max(v,sum[x]);tag[x]=1;} void read(int &x){ char c; bool p=0; while((c=getchar())<'0' || c>'9') if(c=='-') p=1; x=c-'0'; while((c=getchar())>='0' && c<='9') x=x*10+c-'0'; if(p) x=-x; } int New(int &x){ if(top) x=rec[top--]; else x=++cnt; son[x][0]=son[x][1]=rev[x]=tag[x]=0; return x; } void erase(int x){ if(!x) return; rec[++top]=x; erase(son[x][0]),erase(son[x][1]); } void up(int x){ int l=son[x][0],r=son[x][1]; sz[x]=sz[l]+sz[r]+1; sum[x]=sum[l]+sum[r]+val[x]; pre[x]=max(pre[l],sum[l]+val[x]+max(0,pre[r])); suf[x]=max(suf[r],sum[r]+val[x]+max(0,suf[l])); mx[x]=max(max(0,suf[l])+val[x]+max(0,pre[r]),max(mx[l],mx[r])); } void pb(int x){ if(rev[x]){ revl(son[x][0]),revl(son[x][1]); rev[x]=0; } if(tag[x]){ same(son[x][0],val[x]),same(son[x][1],val[x]); tag[x]=0; } } int kth(int k){ int x=o,tmp; while(1){ pb(x); tmp=sz[son[x][0]]+1; if(k==tmp) return x; if(k<tmp) x=son[x][0]; else k-=tmp,x=son[x][1]; } } int build(int l,int r,int fa){ int mid=l+r>>1,x; f[New(x)]=fa,val[x]=a[mid]; if(l<mid) son[x][0]=build(l,mid-1,x); if(r>mid) son[x][1]=build(mid+1,r,x); up(x); return x; } void rotate(int x){ int y=f[x],w=son[y][1]==x; son[y][w]=son[x][w^1]; if(son[x][w^1]) f[son[x][w^1]]=y; if(f[y]) son[f[y]][son[f[y]][1]==y]=x; f[x]=f[y];son[x][w^1]=y;f[y]=x; up(y); } void splay(int x,int w){ int s=1,i=x,y; a[1]=i; while(f[i]) a[++s]=i=f[i]; while(s) pb(a[s--]); while(f[x]!=w){ y=f[x]; if(f[y]!=w){ if((son[f[y]][0]==y)^(son[y][0]==x)) rotate(x); else rotate(y); } rotate(x); } if(!w) o=x; up(x); } int main(){ read(n),read(m); for(int i=1;i<=n;i++) read(a[i]); o=build(0,n+1,0); while(m--){ scanf("%s",op); if(op[2]=='S'){ read(p),read(t); int x=kth(p+1),y=kth(p+2); splay(x,0),splay(y,x); for(int i=0;i<t;i++) read(a[i]); son[y][0]=build(0,t-1,y); up(y),up(x); }else if(op[2]=='L'){ read(p),read(t); int x=kth(p),y=kth(p+t+1); splay(x,0),splay(y,x); erase(son[y][0]); son[y][0]=0; up(y),up(x); }else if(op[2]=='K'){ read(p),read(t),read(c); int x=kth(p),y=kth(p+t+1); splay(x,0),splay(y,x); same(son[y][0],c); up(y),up(x); }else if(op[2]=='V'){ read(p),read(t); int x=kth(p),y=kth(p+t+1); splay(x,0),splay(y,x); revl(son[y][0]); up(y),up(x); }else if(op[2]=='T'){ read(p),read(t); int x=kth(p),y=kth(p+t+1); splay(x,0),splay(y,x); printf("%d\n",sum[son[y][0]]); }else{ int x=kth(1),y=kth(sz[o]); splay(x,0),splay(y,x); printf("%d\n",mx[son[y][0]]); } } return 0; }
相关文章推荐
- BZoj 1500 [NOI2005]维修数列 (Splay 模板)
- BZOJ1500维修数列Splay
- bzoj1500: [NOI2005]维修数列
- 【Splay】BZOJ1500 [NOI2005]维修数列
- bzoj 1500 维修数列
- [BZOJ1500]NOI2005 维修数列|splay
- BZOJ 1500 [NOI2005]维修数列
- bzoj 1500 维修数列 bzoj 1507 editor
- [BZOJ1500][NOI2005]维修数列
- bzoj1500 noi2005 维修数列
- BZOJ 1500: [NOI2005] 维修数列
- bzoj1500 [NOI2005]维修数列解题报告
- [BZOJ]1500 维修数列
- 【bzoj1500】[NOI2005]维修数列
- BZOJ 1500 NOI 2005 维修数列 Splay
- 【bzoj1500】【NOI2005】维修数列
- [BZOJ1500][NOI2005]维修数列(平衡树)
- BZOJ 1500[NOI2005] 维修数列
- [BZOJ1500][NOI2005]维修数列(Splay)
- BZOJ 1500 维护(维修?)数列