BZOJ 1500 NOI2005 维修数列 Splay
2014-09-18 19:50
525 查看
我尽力了。。。从之前的递归版Splay变成非递归,然后各种删除冗余的操作,除了蛋疼的读入优化基本已经精简到底了,连传参都省了-0- 刚交上去是10956MS,差4MS就是BZOJ倒数第一,改完了是9244MS,快了一秒。。。单点测还是死活过不去,等加上读入优化再说吧
题目大意:维护一个序列,支持六种操作:
1.在某个数后面插入一些数字
2.删除从某个数开始的一些数字
3.把从某个数开始的一些数字都改为某个数值
4.把从某个数开始的一些数字翻转顺序
5.求某个数开始的一些数字的和
6.求出某个数开始的一些数字中的最大子序列之和
首先这个题刚出来的时候Splay还没被发明 正解是块状链表 在这里衷心地感谢Tarjan和他的小伙伴们 顺便问候一下他们的家人 辛苦了
妈蛋挂了两个星期的题终于解决了-、-
一开始写的递归版Splay,每次从爷爷里找孙子,这样就不用存爸爸了,结果无限TLE。。。
然后我就卡关了,再没写过Splay-、- 其实这题不难 时间很好卡
这里给出几个要点和优化方式
1.翻转区间的时候不光要兑换左右儿子,还要交换左右最大连续子序列和 这个坑人不浅啊
2.旋转的时候只需要对旋转后的子节点进行Push_Up操作,当Splay操作退出的时候再对该节点Push_Up即可。
3.这不是LCT,旋转之后要更新根节点!切记!
4.修改标记的初值不能是0 因为会有操作把一段区间改成0 所以初值可以弄成一个数据中绝对不会出现的值 比如生日啥的 当然被撞上了就太倒霉了
5.寻找节点时非递归 不然本地调试第八个点和第十个点会爆栈
6.删除的节点必须free 不然妥妥MLE
总之就这么多 这题不好调 耐心点 链式结构去死吧
题目大意:维护一个序列,支持六种操作:
1.在某个数后面插入一些数字
2.删除从某个数开始的一些数字
3.把从某个数开始的一些数字都改为某个数值
4.把从某个数开始的一些数字翻转顺序
5.求某个数开始的一些数字的和
6.求出某个数开始的一些数字中的最大子序列之和
首先这个题刚出来的时候Splay还没被发明 正解是块状链表 在这里衷心地感谢Tarjan和他的小伙伴们 顺便问候一下他们的家人 辛苦了
妈蛋挂了两个星期的题终于解决了-、-
一开始写的递归版Splay,每次从爷爷里找孙子,这样就不用存爸爸了,结果无限TLE。。。
然后我就卡关了,再没写过Splay-、- 其实这题不难 时间很好卡
这里给出几个要点和优化方式
1.翻转区间的时候不光要兑换左右儿子,还要交换左右最大连续子序列和 这个坑人不浅啊
2.旋转的时候只需要对旋转后的子节点进行Push_Up操作,当Splay操作退出的时候再对该节点Push_Up即可。
3.这不是LCT,旋转之后要更新根节点!切记!
4.修改标记的初值不能是0 因为会有操作把一段区间改成0 所以初值可以弄成一个数据中绝对不会出现的值 比如生日啥的 当然被撞上了就太倒霉了
5.寻找节点时非递归 不然本地调试第八个点和第十个点会爆栈
6.删除的节点必须free 不然妥妥MLE
总之就这么多 这题不好调 耐心点 链式结构去死吧
#include<cstdio> #include<cstring> #include<iostream> #include<algorithm> using namespace std; struct max_sequence{ int lmax,rmax,allmax,sum; void un(const max_sequence &x,const max_sequence &y) { allmax=max(x.allmax,y.allmax); allmax=max(allmax,x.rmax+y.lmax); lmax=max(x.lmax,x.sum+y.lmax); rmax=max(y.rmax,y.sum+x.rmax); sum=x.sum+y.sum; } void init(int x,int y) { if(x>0) lmax=rmax=allmax=sum=x*y; else lmax=rmax=allmax=x, sum=x*y; } }; struct abcd{ abcd *fa; abcd *ls,*rs; int size; int num,maxnum; max_sequence ms; int change_mark; bool revmark; void Push_Up(); void Push_Down(); abcd(int x); abcd(); }*null=new abcd,*root=null,*Z,*temp;int Y; abcd :: abcd() { num=maxnum=0xefefefef; size=0; fa=ls=rs=this; ms.init(0xefefefef,0); } abcd :: abcd(int x) { num=maxnum=x; size=1; fa=ls=rs=null; ms.init(x,1); change_mark=19980402; revmark=0; } void abcd :: Push_Up() { //ls->Push_Down(); //rs->Push_Down(); size=ls->size+rs->size+1; maxnum=max(max(ls->maxnum,rs->maxnum),num); ms.init(num,1); ms.un(ls->ms,ms); ms.un(ms,rs->ms); } void abcd :: Push_Down() { if(this==null) return ; if(change_mark^19980402) { ls->change_mark=rs->change_mark=change_mark; ls->num=ls->maxnum=change_mark; rs->num=rs->maxnum=change_mark; ls->ms.init(change_mark,ls->size); rs->ms.init(change_mark,rs->size); change_mark=19980402; } if(revmark) { ls->revmark^=1; rs->revmark^=1; swap(ls->ls,ls->rs); swap(rs->ls,rs->rs); swap(ls->ms.lmax,ls->ms.rmax); swap(rs->ms.lmax,rs->ms.rmax); revmark=0; } } void Zag(abcd *x)//啦啦啦我是左旋 { abcd *y=x->fa; y->Push_Down(); x->Push_Down(); y->rs=x->ls; x->ls->fa=y; x->ls=y; x->fa=y->fa; if(y==y->fa->ls) y->fa->ls=x; else if(y==y->fa->rs) y->fa->rs=x; y->fa=x; y->Push_Up(); if(root==y) root=x; } void Zig(abcd *x)//啦啦啦我是右旋 { abcd *y=x->fa; y->Push_Down(); x->Push_Down(); y->ls=x->rs; x->rs->fa=y; x->rs=y; x->fa=y->fa; if(y==y->fa->ls) y->fa->ls=x; else if(y==y->fa->rs) y->fa->rs=x; y->fa=x; y->Push_Up(); if(root==y) root=x; } void Splay(abcd *x) { while(1) { abcd *y=x->fa,*z=y->fa; if(y==Z) break; if(z==Z) { if(x==y->ls) Zig(x); else Zag(x); break; } if(x==y->ls) { if(y==z->ls) Zig(y); Zig(x); } else { if(y==z->rs) Zag(y); Zag(x); } } x->Push_Up(); } void Find(abcd *x) { while(1) { x->Push_Down(); if(Y<=x->ls->size) x=x->ls; else{ Y-=x->ls->size; if(Y==1) break; Y--; x=x->rs; } } Splay(x); } void Insert(abcd *&x,int y,abcd *from) { if(x==null) { x=new abcd(y); x->fa=from; Z=null; Splay(x); return ; } x->Push_Down(); Insert(x->rs,y,x); } void Free(abcd *x) { if(x==null) return ; Free(x->ls); Free(x->rs); free(x); } void INSERT() { int i,x,pos,tot; scanf("%d%d",&pos,&tot); Y=pos+1,Z=null,Find(root); Y=pos+2,Z=root,Find(root); temp=root;root=null; for(i=1;i<=tot;i++) scanf("%d",&x),Insert(root,x,null); temp->rs->ls=root; root->fa=temp->rs; root=temp; root->rs->Push_Up(); root->Push_Up(); } void DELETE() { int pos,tot; scanf("%d%d",&pos,&tot); Y=pos,Z=null,Find(root); Y=pos+tot+1,Z=root,Find(root); temp=root->rs->ls; root->rs->ls=null; root->rs->Push_Up(); root->Push_Up(); Free(temp); } void MAKE_SAME() { int pos,tot,c; scanf("%d%d%d",&pos,&tot,&c); Y=pos,Z=null,Find(root); Y=pos+tot+1,Z=root,Find(root); root->rs->ls->change_mark=c; temp=root->rs->ls; temp->num=temp->maxnum=c; temp->ms.init(c,temp->size); root->rs->Push_Up(); root->Push_Up(); } void REVERSE() { int pos,tot; scanf("%d%d",&pos,&tot); Y=pos,Z=null,Find(root); Y=pos+tot+1,Z=root,Find(root); temp=root->rs->ls; temp->revmark^=1; swap(temp->ls,temp->rs); swap(temp->ms.lmax,temp->ms.rmax); } void GET_SUM() { int pos,tot; scanf("%d%d",&pos,&tot); Y=pos,Z=null,Find(root); Y=pos+tot+1,Z=root,Find(root); printf("%d\n",root->rs->ls->ms.sum); } void MAX_SUM() { Y=1,Z=null,Find(root); Y=root->size,Z=root,Find(root); printf("%d\n",root->rs->ls->ms.allmax); } int n,m; int main() { //freopen("sequence.in","r",stdin); //freopen("sequence.out","w",stdout); int i,x; char p[20]; scanf("%d%d",&n,&m); Insert(root,0,null); for(i=1;i<=n;i++) { scanf("%d",&x); Insert(root,x,null); } Insert(root,0,null); for(i=1;i<=m;i++) { scanf("%s",p); if(p[2]=='S')INSERT(); else if(p[2]=='L')DELETE(); else if(p[2]=='K')MAKE_SAME(); else if(p[2]=='V')REVERSE(); else if(p[2]=='T')GET_SUM(); else if(p[2]=='X')MAX_SUM(); } }
相关文章推荐
- [bzoj1500][NOI2005]维修数列——splay
- BZOJ 1500 [NOI2005]维修数列 (splay)
- 【BZOJ1500】【NOI2005】维修数列(Splay)
- 【splay】BZOJ 1500: [NOI2005]维修数列
- 【BZOJ】1500 [NOI2005]维修数列 【splay】
- 【BZOJ1500】[NOI2005]维修数列 Splay
- [BZOJ1500][NOI2005]维修数列(Splay)
- [NOI2005] [BZOJ1500] 维修数列 - splay
- 【bzoj1500】[NOI2005]维修数列 Splay
- BZOJ1500: [NOI2005]维修数列 [splay序列操作]【学习笔记】
- BZOJ 1500 [NOI2005]维修数列(splay)
- 【bzoj1500】[NOI2005]维修数列 Splay
- [BZOJ1500][NOI2005][Splay]维修数列
- BZOJ 1500|NOI 2005|维修数列|Splay
- BZOJ 1500([NOI2005]维修数列-Splay的数列维护)
- [bzoj1500][NOI2005 维修数列] (splay区间操作)
- 【bzoj1500】[NOI2005]维修数列 Splay
- BZOJ 1500: [NOI2005]维修数列 Splay
- BZOJ1500: [NOI2005]维修数列 Splay
- BZOJ_1500_[NOI2005]维修数列_splay