模板 文艺平衡树
Posted blog-dr-j
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了模板 文艺平衡树相关的知识,希望对你有一定的参考价值。
Splay模板,学完觉得比Treap简单,不过均摊的logn不能可持久化。
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 #define ls ch[0] 5 #define rs ch[1] 6 struct trnt{ 7 int ch[2]; 8 int chd; 9 int wgt; 10 int fa; 11 int v; 12 }tr[10000000]; 13 int root; 14 int siz; 15 int n,m; 16 namespace SPLAY{ 17 void Spushup(int spc) 18 { 19 tr[spc].wgt=tr[tr[spc].ch[0]].wgt+tr[tr[spc].ch[1]].wgt+1; 20 return ; 21 } 22 void Spushdown(int spc) 23 { 24 if(tr[spc].chd) 25 { 26 tr[tr[spc].ch[0]].chd^=1; 27 tr[tr[spc].ch[1]].chd^=1; 28 std::swap(tr[tr[spc].ls].ls,tr[tr[spc].ls].rs); 29 std::swap(tr[tr[spc].rs].ls,tr[tr[spc].rs].rs); 30 tr[spc].chd=0; 31 } 32 } 33 bool plc(int spc) 34 { 35 return tr[tr[spc].fa].rs==spc; 36 } 37 void Sroutate(int spc) 38 { 39 int f=tr[spc].fa; 40 bool k=plc(spc); 41 tr[f].ch[k]=tr[spc].ch[!k]; 42 tr[spc].ch[!k]=f; 43 tr[tr[f].fa].ch[plc(f)]=spc; 44 tr[spc].fa=tr[f].fa; 45 tr[f].fa=spc; 46 tr[tr[f].ch[k]].fa=f; 47 Spushup(spc); 48 Spushup(f); 49 } 50 void Splay(int spc,int f) 51 { 52 while(tr[spc].fa!=f) 53 { 54 int ft=tr[spc].fa; 55 if(tr[ft].fa==f) 56 { 57 Sroutate(spc); 58 break; 59 } 60 if(plc(spc)^plc(ft)) 61 Sroutate(spc); 62 else 63 Sroutate(ft); 64 Sroutate(spc); 65 } 66 if(!f) 67 root=spc; 68 } 69 int Splace(int spc,int rk) 70 { 71 Spushdown(spc); 72 if(tr[tr[spc].ls].wgt>=rk) 73 return Splace(tr[spc].ls,rk); 74 else if(tr[tr[spc].ls].wgt+1==rk) 75 return spc; 76 else 77 return Splace(tr[spc].rs,rk-tr[tr[spc].ls].wgt-1); 78 } 79 void Supdate(int l,int r) 80 { 81 int plc1,plc2; 82 plc1=Splace(root,l-1); 83 Splay(plc1,0); 84 plc2=Splace(root,r+1); 85 Splay(plc2,plc1); 86 int spc=tr[plc2].ls; 87 std::swap(tr[spc].ls,tr[spc].rs); 88 tr[spc].chd^=1; 89 } 90 void Sbuild(int l,int r,int &spc,int f) 91 { 92 if(l>r) 93 return ; 94 spc=++siz; 95 int mid=(l+r)>>1; 96 tr[spc].v=mid; 97 tr[spc].fa=f; 98 Sbuild(l,mid-1,tr[spc].ls,spc); 99 Sbuild(mid+1,r,tr[spc].rs,spc); 100 Spushup(spc); 101 return ; 102 } 103 void Sprint(int spc) 104 { 105 if(!spc) 106 return ; 107 Spushdown(spc); 108 Sprint(tr[spc].ls); 109 printf("%d ",tr[spc].v); 110 Sprint(tr[spc].rs); 111 return ; 112 } 113 } 114 int main() 115 { 116 scanf("%d%d",&n,&m); 117 SPLAY::Sbuild(0,n+1,root,0); 118 for(int i=1;i<=m;i++) 119 { 120 int l,r; 121 scanf("%d%d",&l,&r); 122 SPLAY::Supdate(l+1,r+1); 123 } 124 int org,fin; 125 org=SPLAY::Splace(root,1); 126 SPLAY::Splay(org,0); 127 fin=SPLAY::Splace(root,siz); 128 SPLAY::Splay(fin,root); 129 SPLAY::Sprint(tr[tr[root].rs].ls); 130 puts(""); 131 return 0; 132 }
以上是关于模板 文艺平衡树的主要内容,如果未能解决你的问题,请参考以下文章