1. 程式人生 > >splay 文藝平衡樹 (數據結構)

splay 文藝平衡樹 (數據結構)

def data pac 區間 efi 中序遍歷 root n+1 維護

題目大意:略

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 文藝平衡樹 (數據結構)