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 }
原文地址:https://www.cnblogs.com/guapisolo/p/9697023.html