【Splay操作】续.....
2016-02-11 23:14
447 查看
#include<iostream> #include<algorithm> #include<stdio.h> #define maxn (200005) using namespace std; int ch[maxn][2],val[maxn],size[maxn],f[maxn]; int root,tot,n,m,a[maxn],add[maxn],sum[maxn],lazy[maxn]; int ans[maxn],R[maxn],L[maxn]; bool flip[maxn]; inline void pushdown(int x) { if (flip[x]!=0) { flip[ch[x][0]]^=1; flip[ch[x][1]]^=1; swap(ch[x][0],ch[x][1]); flip[x]=0; } if(ch[x][0]) add[ch[x][0]]+=add[x]; if(ch[x][1]) add[ch[x][1]]+=add[x]; val[x]+=add[x]; add[x]=0; if (lazy[x]) { if(ch[x][0]) lazy[ch[x][0]]=lazy[x]; if(ch[x][1]) lazy[ch[x][1]]=lazy[x]; val[x]=lazy[x]; sum[x]=lazy[x]*size[x]; lazy[x]=0; } } inline void pushup(int x) { size[x]=size[ch[x][0]]+size[ch[x][1]]+1; if (lazy[ch[x][0]]) pushdown(ch[x][0]); if (lazy[ch[x][1]]) pushdown(ch[x][1]); sum[x]=sum[ch[x][0]]+sum[ch[x][1]]+val[x]; sum[x]+=add[ch[x][0]]*size[ch[x][0]]+add[ch[x][1]]*size[ch[x][1]]; ans[x]=max(max(ans[ch[x][0]],ans[ch[x][1]]),R[ch[x][1]]+L[ch[x][0]]+val[x]); L[x]=max(L[ch[x][1]],sum[ch[x][1]]+val[x]+L[ch[x][0]]); R[x]=max(R[ch[x][0]],sum[ch[x][0]]+val[x]+R[ch[x][1]]); } inline void push(int x) { pushdown(x); pushup(x); } inline int is(int x) { return ch[f[x]][1]==x; } inline void link(int y,int x,int d) { if (x) f[x]=y; ch[y][d]=x; if (x) pushup(x); pushup(y); } inline void newnode(int &x,int fa,int v) { tot++; x=tot; f[x]=fa; val[x]=v; if (fa==0) x=0; if (x) pushup(x); if (fa) pushup(fa); } inline void rotate(int x,int d) { int y=f[x]; int z=f[y]; pushdown(z); pushdown(y); pushdown(x); link(y,ch[x][!d],d); if (z) link(z,x,is(y)); f[x]=z; link(x,y,!d); if (z) pushup(z); } inline void zig(int x) { rotate(x,1); } inline void zag(int x) { rotate(x,0); } inline void splay(int x,int goal=0) { pushdown(x); while (f[x]!=goal) { int y=f[x]; int z=f[y]; if (z==goal) { rotate(x,is(x)); break; } if (ch[z][1]==y) { if (ch[y][1]==x) zig(y),zig(x); else zag(x),zig(x); } else { if (ch[y][0]==x) zag(y),zag(x); else zig(x),zag(x); } pushup(x); } if (goal==0) root=x; pushup(x); if (goal) pushup(goal); } inline int pre(int x) { splay(x); x=ch[x][1]; while(ch[x][0]) x=ch[x][0]; return x; } inline int nex(int x) { splay(x); x=ch[x][0]; while(ch[x][1]) x=ch[x][1]; return x; } inline void insert(int v) { int x=root; while(ch[x][v<val[x]]) x=ch[x][v<val[x]]; newnode(ch[x][v<val[x]],x,v); splay(tot); } inline int getnum(int k,int x) { pushdown(x); if (x) pushup(x); if(size[ch[x][1]]+1==k) return x; else if (size[ch[x][1]]+1<k) return getnum(k-size[ch[x][1]]-1,ch[x][0]); else return getnum(k,ch[x][1]); } inline int build(int l,int r) { if (l>r) return 0; tot++; int t=tot; int mid=(l+r)/2; val[t]=a[mid]; link(t,build(l,mid-1),1); link(t,build(mid+1,r),0); return t; } inline void insert_line(int k,int num) { for (int i=1;i<=num;i++) scanf("%d",&a[i]); if (root==0) { root=build(1,num); return ; } int totk; if (k) totk=getnum(k,root); else totk=getnum(1,root); int nexk=nex(totk); if (nexk==0) link(totk,build(1,num),0); else { splay(totk); splay(nexk,totk); if (k==0) link(totk,build(1,num),1); else link(nexk,build(1,num),1); } } inline void del(int l,int r) { r=l+r-1; l=getnum(l,root); r=getnum(r,root); int prel=pre(l); int nexr=nex(r); if (prel==0&&nexr==0) root=0; else if (prel==0) splay(nexr),ch[nexr][1]=0,pushup(nexr); else if (nexr==0) splay(prel),ch[prel][0]=0,pushup(prel); else { splay(prel); splay(nexr,prel); ch[nexr][1]=0; pushup(nexr); } } inline void rev(int l,int r) { r=l+r-1; l=getnum(l,root); r=getnum(r,root); int prel=pre(l); int nexr=nex(r); if (prel==0&&nexr==0) flip[root]^=1; else if (prel==0) { splay(nexr); flip[ch[nexr][1]]^=1; } else if (nexr==0) { splay(prel); flip[ch[prel][0]]^=1; } else { splay(prel); splay(nexr,prel); flip[ch[nexr][1]]^=1; pushup(nexr); } } inline void addv(int l,int r,int v) { r=l+r-1; l=getnum(l,root); r=getnum(r,root); int prel=pre(l); int nexr=nex(r); if (prel==0&&nexr==0) add[root]+=v,push(root); else if (prel==0) { splay(nexr); add[ch[nexr][1]]+=v; pushup(nexr); } else if (nexr==0) { splay(prel); add[ch[prel][0]]+=v; pushup(prel); } else { splay(prel); splay(nexr,prel); add[ch[nexr][1]]+=v; pushup(nexr); pushup(prel); } } inline int query(int l,int r) { r=l+r-1; l=getnum(l,root); r=getnum(r,root); int prel=pre(l); int nexr=nex(r); if (prel==0&&nexr==0) printf("%d\n",sum[root]); else if (prel==0) { splay(nexr); printf("%d\n",sum[ch[nexr][1]]); } else if (nexr==0) { splay(prel); printf("%d\n",sum[ch[prel][0]]); } else { splay(prel); splay(nexr,prel); printf("%d\n",sum[ch[nexr][1]]); } } inline void change(int l,int r,int v) { r=l+r-1; l=getnum(l,root); r=getnum(r,root); int prel=pre(l); int nexr=nex(r); if (prel==0&&nexr==0) lazy[root]=v,pushdown(root),pushup(root); else if (prel==0) { splay(nexr); lazy[ch[nexr][1]]=v; pushdown(ch[nexr][1]); pushup(ch[nexr][1]); pushup(nexr); } else if (nexr==0) { splay(prel); lazy[ch[prel][0]]=v; pushdown(ch[prel][0]); pushup(ch[prel][0]); pushup(prel); } else { splay(prel); splay(nexr,prel); lazy[ch[nexr][1]]=v; pushdown(ch[nexr][1]); pushup(ch[nexr][1]); pushup(nexr); pushup(prel); } } //void putt() //{ // for (int i=1;i<=tot;i++) // cout<<ch[i][0]<<' '<<ch[i][1]<<' '<<sum[i]<<endl; //} int main() { scanf("%d%d",&n,&m); for (int i=1;i<=n;i++) scanf("%d",&a[i]); root=build(1,n); f[root]=0; // for (int j=1;j<=20;j++) // cout<<val[getnum(j,root)]<<' '; // cout<<endl; for (int i=1;i<=m;i++) { // putt(); // cout<<endl; char c[20]; int a,b,lps; scanf("%s",c); if (c[0]=='M'&&c[2]=='X') cout<<ans[root]<<endl; else { scanf("%d%d",&a,&b); if (c[0]=='R')//反转一个序列 rev(a,b); else if (c[0]=='D')//删除一个序列 del(a,b); else if (c[0]=='I')//插入一个序列 insert_line(a,b); else if (c[0]=='A')//区间加值 scanf("%d",&lps),addv(a,b,lps); else if (c[0]=='G')//区间求和 query(a,b); else if (c[0]=='M'&&c[2]=='K') scanf("%d",&lps),change(a,b,lps); //把一个区间内所有元素都改成一个给定的值 } cout<<sum[root]<<endl; for (int j=1;j<=20;j++) cout<<val[getnum(j,root)]<<' '; cout<<"root :"<<val[root]<<endl; cout<<endl; } }
变量定义参考之前的博客,之前的splay貌似有点问题,pushup和pushdown处理的不对,若有人被坑害,就很抱歉啦,这次这个经本人测验除了求区间最大子段和外其他操作已没有问题,因为改变了各个点的值之后,我不太会继续维持最大子段和,因此若是各位菊苣知道怎么办欢迎评论指导,我自己再摸索会….orz
相关文章推荐
- 面向对象思想
- 堆(Heap)
- async 异步进度条,防UI卡顿
- Codeforces 332B Maximum Absurdity(暴力)
- I - Long Distance Racing(第二季水)
- VS2015中cout、cin未声明的标识符错误的处理
- 111. Minimum Depth of Binary Tree LeetCode
- 基于MySQLi和jQuery的评论系统
- 225. Implement Stack using Queues LeetCode
- Codeforces 519D A and B and Interesting Substrings (简单hash)
- 【CodeForces 618C】Constellation
- java基础12多线程
- 9. Palindrome Number LeetCode
- bzoj1005: [HNOI2008]明明的烦恼
- 基于SDP的提议/应答(offer/answer)模型简介
- javascript笔记7-事件
- 【Codeforces 282E】Sausage Maximization 中文题意&题解&代码(C++)
- Linux文件和目录的读、写、执行权限总结
- Atitit..net clr il指令集 以及指令分类 与指令详细说明
- 112. Path Sum LeetCode