splay 文艺平衡树 (数据结构)
Posted guapisolo
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了splay 文艺平衡树 (数据结构)相关的知识,希望对你有一定的参考价值。
题目大意:略
splay维护区间翻转裸题,为了减少不必要的麻烦,多插入两个点,分别是0和n+1
每次找区间的第K个值,就在splay上二分即可
顺便学了一下splay的完美建树,而且splay有一些小函数可以宏定义或者用inline,跑得飞快
最后跑一遍中序遍历即可
1 #include <cstdio> 2 #include <cstring> 3 #include <algorithm> 4 #define N 100100 5 #define il inline 6 #define ll long long 7 #define root d[0].ch[1] 8 #define con(x,ff,p) d[x].fa=ff,d[ff].ch[p]=x 9 #define idf(x) d[d[x].fa].ch[0]==x?0:1 10 #define lb(x) (x&(-x)) 11 using namespace std; 12 13 int n,m,cnt; 14 struct SPLAY{ 15 int fa,ch[2],id,sum,mrk; 16 }d[N<<1]; 17 il void pushup(int x) {d[x].sum=d[d[x].ch[0]].sum+d[d[x].ch[1]].sum+1;} 18 il void pushdown(int x) 19 { 20 if(!d[x].mrk) return; 21 swap(d[x].ch[0],d[x].ch[1]); 22 d[x].mrk=0; 23 d[d[x].ch[0]].mrk^=1; 24 d[d[x].ch[1]].mrk^=1; 25 } 26 il void rot(int x) 27 { 28 int y=d[x].fa;int ff=d[y].fa; 29 int px=idf(x);int py=idf(y); 30 con(d[x].ch[px^1],y,px); 31 con(y,x,px^1); 32 con(x,ff,py); 33 pushup(y),pushup(x); 34 } 35 void splay(int x,int to) 36 { 37 to=d[to].fa; 38 int y,px,py; 39 while(d[x].fa!=to) 40 { 41 y=d[x].fa; 42 px=idf(y),py=idf(x); 43 if(d[y].fa==to) rot(x); 44 else if(py==px){ 45 rot(y); 46 rot(x); 47 }else{ 48 rot(x); 49 rot(x); 50 } 51 } 52 } 53 int Find(int w) 54 { 55 int x=root; 56 while(x) 57 { 58 pushdown(x); 59 if(d[d[x].ch[0]].sum>=w) 60 { 61 x=d[x].ch[0]; 62 continue; 63 } 64 w-=d[d[x].ch[0]].sum; 65 if(w==1) return x; 66 w--,x=d[x].ch[1]; 67 } 68 return 0; 69 } 70 int build(int ff,int l,int r) 71 { 72 if(l>r) return 0; 73 int x=++cnt; 74 int mid=(l+r)>>1; 75 d[x].id=mid-1,d[x].fa=ff,d[x].sum=1; 76 d[x].ch[0]=build(x,l,mid-1); 77 d[x].ch[1]=build(x,mid+1,r); 78 pushup(x); 79 return x; 80 } 81 void Print(int x) 82 { 83 pushdown(x); 84 if(d[x].ch[0]) Print(d[x].ch[0]); 85 if(d[x].id!=0&&d[x].id!=n+1) printf("%d ",d[x].id); 86 if(d[x].ch[1]) Print(d[x].ch[1]); 87 } 88 int main() 89 { 90 //freopen("testdata.in","r",stdin); 91 scanf("%d%d",&n,&m); 92 int x,y; 93 root=build(0,1,n+2); 94 for(int i=1;i<=m;i++){ 95 scanf("%d%d",&x,&y); 96 if(x==y) continue; 97 int xx=Find(x); 98 splay(xx,root); 99 int yy=Find(y+2); 100 splay(yy,d[root].ch[1]); 101 d[d[d[root].ch[1]].ch[0]].mrk^=1; 102 } 103 Print(root); 104 return 0; 105 }
以上是关于splay 文艺平衡树 (数据结构)的主要内容,如果未能解决你的问题,请参考以下文章