poj 3580 super-memo 非旋treap/splay 模板
2017-02-14 15:33
627 查看
题目大意
分析
模版题就不分析了非旋treap/splay
注意
splay插入,revolve后重新连边后要连父亲splay中不要pushup(你提取出来的那一段)
因为那没有pushdown的,pushup会有bug
solution1(splay)
#include <cstdio> #include <cstring> #include <cstdlib> #include <cctype> #include <cmath> #include <algorithm> typedef long long LL; using namespace std; const int M=200007; inline int rd(){ int x=0;bool f=1;char c=getchar(); for(;!isdigit(c);c=getchar()) if(c=='-') f=0; for(;isdigit(c);c=getchar()) x=x*10+c-48; return f?x:-x; } inline LL lrd(){ LL x=0;bool f=1;char c=getchar(); for(;!isdigit(c);c=getchar()) if(c=='-') f=0; for(;isdigit(c);c=getchar()) x=x*10+c-48; return f?x:-x; } int n,m; LL fir[M]; char s[13]; struct SPLAY{ int ch[2],p; int rev,sz; LL tag,val,mn; void init(LL d){ val=mn=d; tag=0; rev=0; sz=1; ch[0]=ch[1]=p=0; } }a[M]; int tot,rt; void totag(int x,LL d){ a[x].val+=d; a[x].mn+=d; a[x].tag+=d; } void torev(int x){ a[x].rev^=1; } void pushup(int x){ a[x].mn=a[x].val; a[x].sz=1; if(a[x].ch[0]){ a[x].mn=min(a[x].mn,a[a[x].ch[0]].mn); a[x].sz+=a[a[x].ch[0]].sz; } if(a[x].ch[1]){ a[x].mn=min(a[x].mn,a[a[x].ch[1]].mn); a[x].sz+=a[a[x].ch[1]].sz; } } void pushdown(int x){ if(a[x].rev){ if(a[x].ch[0]) torev(a[x].ch[0]); if(a[x].ch[1]) torev(a[x].ch[1]); swap(a[x].ch[0],a[x].ch[1]); a[x].rev^=1; } if(a[x].tag){ if(a[x].ch[0]) totag(a[x].ch[0],a[x].tag); if(a[x].ch[1]) totag(a[x].ch[1],a[x].tag); a[x].tag=0; } } int build(int l,int r){ if(l>r) return 0; int x=l+r>>1; a[x].init(fir[x]); a[x].ch[0]=build(l,x-1); a[x].ch[1]=build(x+1,r); if(a[x].ch[0]) a[a[x].ch[0]].p=x; if(a[x].ch[1]) a[a[x].ch[1]].p=x; pushup(x); return x; } int find_kth(int x,int kth){ if(!x) return 0; pushdown(x); int cnt=a[a[x].ch[0]].sz+1; if(kth==cnt) return x; if(kth<cnt) return find_kth(a[x].ch[0],kth); else return find_kth(a[x].ch[1],kth-cnt); } void rot(int x){ int y=a[x].p; int z=a[y].p; int D=a[y].ch[1]==x,ss=D^1; if(z) a[z].ch[a[z].ch[1]==y]=x; a[x].p=z; a[y].p=x; if(a[x].ch[ss]) a[a[x].ch[ss]].p=y; a[y].ch[D]=a[x].ch[ss]; a[x].ch[ss]=y; pushup(y); pushup(x); } void splay(int x){ int y,z; for(;a[x].p;rot(x)){ y=a[x].p; z=a[y].p; if(!z) continue; if(z==rt) rot(x); else if((a[z].ch[0]==y)==(a[y].ch[0]==x)) rot(y); else rot(x); } } int Spl(int kth){ kth++; int x=find_kth(rt,kth); splay(x); rt=x; return x; } void Add(int l,int r,LL d){ int x=Spl(l-1); int y=Spl(r+1); int z=a[x].ch[1]; totag(z,d); pushup(x); pushup(y); } void Ins(int l,LL d){ int x=Spl(l); int y=Spl(l+1); int z=a[x].ch[1]=++tot; a[z].init(d); a[z].p=x;//**** pushup(x); pushup(y); } void Del(int l){ int x=Spl(l-1); int y=Spl(l+1); a[x].ch[1]=0; pushup(x); pushup(y); } void Getmin(int l,int r){ int x=Spl(l-1); int y=Spl(r+1); int z=a[x].ch[1]; printf("%lld\n",a[z].mn); pushup(x); pushup(y); } void Reverse(int l,int r){ int x=Spl(l-1); int y=Spl(r+1); int z=a[x].ch[1]; torev(z); pushup(x); pushup(y); } void Revolve(int l,int r,int mid){ int x=Spl(mid); int y=Spl(r+1); int z=a[x].ch[1]; a[x].ch[1]=0; pushup(x); pushup(y); x=Spl(l-1); y=Spl(l); a[x].ch[1]=z; a[z].p=x;//****** pushup(x); pushup(y); } int main(){ int i,x,y,tms; LL z; n=rd(); for(i=1;i<=n;i++) fir[i]=lrd(); x=build(1,n); tot=n+2;rt=n+1; a[n+1].init(-1); a[n+2].init(-1); a[n+1].ch[1]=n+2; a[n+2].p=n+1; a[n+2].ch[0]=x; a[x].p=n+2; pushup(n+2); pushup(n+1); m=rd(); while(m--){ scanf("%s",s); if(s[0]=='A'){ x=rd();y=rd();z=lrd(); Add(x,y,z); } else if(s[0]=='I'){ x=rd();z=lrd(); Ins(x,z); } else if(s[0]=='D'){ x=rd(); Del(x); } else if(s[0]=='M'){ x=rd(),y=rd(); Getmin(x,y); } else if(s[3]=='E'){ x=rd(),y=rd(); Reverse(x,y); } else{ x=rd(),y=rd(); tms=rd(); int len=y-x+1; tms=(tms%len+len)%len; tms=len-tms; if(tms==len)continue; Revolve(x,y,x+tms-1); } } return 0; }
solution2
#include <cstdio> #include <cstring> #include <cstring> #include <cctype> #include <cmath> #include <algorithm> using namespace std; typedef long long LL; const int M=200007; inline int rd(){ int x=0;bool f=1;char c=getchar(); for(;!isdigit(c);c=getchar()) if(c=='-') f=0; for(;isdigit(c);c=getchar()) x=x*10+c-48; return f?x:-x; } inline LL lrd(){ LL x=0;bool f=1;char c=getchar(); for(;!isdigit(c);c=getchar()) if(c=='-') f=0; for(;isdigit(c);c=getchar()) x=x*10+c-48; return x; } int n,m; char s[13]; struct DR{ int ch[2]; DR(){ch[0]=ch[1]=0;} }; struct Treap{ LL val,mn,tag; int rev,fix,sz; int ch[2]; void init(LL d){ val=mn=d; tag=0; rev=0; fix=rand(); ch[0]=ch[1]=0; sz=1; } }a[M]; int root,tot; void totag(int x,LL z){ a[x].val+=z; a[x].mn+=z; a[x].tag+=z; } void torev(int x){ a[x].rev^=1; } void pushup(int x){ a[x].mn=a[x].val; a[x].sz=1; if(a[x].ch[0]){ a[x].mn=min(a[x].mn,a[a[x].ch[0]].mn); a[x].sz+=a[a[x].ch[0]].sz; } if(a[x].ch[1]){ a[x].mn=min(a[x].mn,a[a[x].ch[1]].mn); a[x].sz+=a[a[x].ch[1]].sz; } } void pushdown(int x){ if(a[x].rev){ if(a[x].ch[0]) torev(a[x].ch[0]); if(a[x].ch[1]) torev(a[x].ch[1]); swap(a[x].ch[0],a[x].ch[1]); a[x].rev^=1; } if(a[x].tag){ if(a[x].ch[0]) totag(a[x].ch[0],a[x].tag); if(a[x].ch[1]) totag(a[x].ch[1],a[x].tag); a[x].tag=0; } } DR split_kth(int x,int kth){ DR y; if(!x) return y; pushdown(x); int cnt=1; if(a[x].ch[0]) cnt+=a[a[x].ch[0]].sz; if(cnt==kth){ y.ch[1]=a[x].ch[1]; a[x].ch[1]=0; pushup(x); y.ch[0]=x; return y; } else if(kth<cnt){ y=split_kth(a[x].ch[0],kth); a[x].ch[0]=y.ch[1]; pushup(x); y.ch[1]=x; return y; } else{ y=split_kth(a[x].ch[1],kth-cnt); a[x].ch[1]=y.ch[0]; pushup(x); y.ch[0]=x; return y; } } int merge(int x,int y){ if(!x) return y; if(!y) return x; if(a[x].fix<a[y].fix){ pushdown(x); a[x].ch[1]=merge(a[x].ch[1],y); pushup(x); return x; } else{ pushdown(y); a[y].ch[0]=merge(x,a[y].ch[0]); pushup(y); return y; } } void Add(int x,int y,LL z){ DR n2=split_kth(root,y); DR n1=split_kth(n2.ch[0],x-1); totag(n1.ch[1],z); root=merge(merge(n1.ch[0],n1.ch[1]),n2.ch[1]); } void Ins(int x,LL z){ a[++tot].init(z); DR n1=split_kth(root,x); root=merge(merge(n1.ch[0],tot),n1.ch[1]); } void Del(int x){ DR n2=split_kth(root,x); DR n1=split_kth(n2.ch[0],x-1); root=merge(n1.ch[0],n2.ch[1]); } void Getmin(int x,int y){ DR n2=split_kth(root,y); DR n1=split_kth(n2.ch[0],x-1); printf("%lld\n",a[n1.ch[1]].mn); root=merge(merge(n1.ch[0],n1.ch[1]),n2.ch[1]); } void Reverse(int x,int y){ DR n2=split_kth(root,y); DR n1=split_kth(n2.ch[0],x-1); torev(n1.ch[1]); root=merge(merge(n1.ch[0],n1.ch[1]),n2.ch[1]); } void Revolve(int x,int y,int z){ DR n2=split_kth(root,y); DR n1=split_kth(n2.ch[0],x-1); DR nw=split_kth(n1.ch[1],z); root=merge(merge(n1.ch[0],merge(nw.ch[1],nw.ch[0])),n2.ch[1]); } int main(){ int i,x,y,tms; LL z; n=rd(); for(i=1;i<=n;i++){ z=lrd(); a[i].init(z); } root=0; tot=n; for(i=1;i<=n;i++) root=merge(root,i); m=rd(); while(m--){ scanf("%s",s); if(s[0]=='A'){ x=rd(),y=rd(); z=lrd(); Add(x,y,z); } else if(s[0]=='I'){ x=rd(); z=lrd(); Ins(x,z); } else if(s[0]=='D'){ x=rd(); Del(x); } else if(s[0]=='M'){ x=rd(),y=rd(); Getmin(x,y); } else if(s[3]=='E'){ x=rd(),y=rd(); Reverse(x,y); } else{ x=rd(),y=rd(),tms=rd(); int llen=y-x+1; tms=(tms%llen+llen)%llen; tms=llen-tms; if(tms==llen) continue; Revolve(x,y,tms); } } return 0; }
相关文章推荐
- SQL基本语句
- Linux开机启动程序详解
- 【转】探索 ConcurrentHashMap 高并发性的实现机制
- 91.Spring Boot属性spring.datasource.type特别篇
- Java实现几种常见排序方法
- Hibernate 缓存机制
- 递归删除-优化
- html5 Canvas画图6:画曲线之arcTo
- QT学习之路三(模态和非模态对话框)
- 算法题--字符排列(全排列)
- linux c之通过popen和pclose函数创建管道执行shell 运行命令使用总结
- Android性能优化的方方面面
- HorizontalScrollView 和GridView 实现横向滑动
- go-操作oracle数据库
- 润乾自定义数据集发布报表报空指针异常
- Js数组的基本方法2
- Android黑名单自动挂断来电(AIDL)
- 优化Mysql数据库的方法
- Redis 如何存储一条用户信息
- 使用ssh无法连接虚拟机linux系统