首页 > 代码库 > P3391 【模板】文艺平衡树(Splay)

P3391 【模板】文艺平衡树(Splay)

P3391 【模板】文艺平衡树(Splay)

题目背景

这是一道经典的Splay模板题——文艺平衡树。

题目描述

您需要写一种数据结构(可参考题目标题),来维护一个有序数列,其中需要提供以下操作:翻转一个区间,例如原有序序列是5 4 3 2 1,翻转区间是[2,4]的话,结果是5 2 3 4 1

输入输出格式

输入格式:

 

第一行为n,m n表示初始序列有n个数,这个序列依次是(1,2, \cdots n-1,n)(1,2,?n1,n) m表示翻转操作次数

接下来m行每行两个数 [l,r][l,r] 数据保证 1 \leq l \leq r \leq n1lrn

 

输出格式:

 

输出一行n个数字,表示原始序列经过m次变换后的结果

 

输入输出样例

输入样例#1:
5 31 31 31 4
输出样例#1:
4 3 2 1 5

说明

n, m \leq 100000n,m100000

code

  1 #include<cstdio>  2 #include<algorithm>  3   4 using namespace std;  5   6 const int MAXN = 100100;  7 int fa[MAXN],ch[MAXN][2],tag[MAXN],siz[MAXN],id[MAXN];  8 int n,m,root,sz;  9  10 int read() 11 { 12     int x = 0;char ch = getchar(); 13     while (ch<0||ch>9) ch = getchar(); 14     while (ch>=0&&ch<=9) x = x*10+ch-0,ch = getchar(); 15     return x; 16 } 17 void pushup(int x) 18 { 19     siz[x] = siz[ch[x][0]] + siz[ch[x][1]] + 1; 20 } 21 void pushdown(int x) 22 { 23     if (tag[x]) 24     { 25         tag[ch[x][0]] ^= 1; 26         tag[ch[x][1]] ^= 1; 27         swap(ch[x][0],ch[x][1]); 28         tag[x] = 0; 29     } 30 } 31 int son(int x) 32 { 33     return ch[fa[x]][1]==x; 34 } 35 void rotate(int x) 36 { 37     int y = fa[x],z = fa[y],b = son(x),c = son(y),a = ch[x][!b]; 38     if (z) ch[z][c] = x;else root = x;fa[x] = z; 39     if (a) fa[a] = y;ch[y][b] = a; 40     ch[x][!b] = y;fa[y] = x; 41     pushup(y); 42 } 43 void splay(int &x,int rt) 44 { 45     while (fa[x]!=rt) 46     { 47         int y = fa[x],z = fa[y]; 48         if (z==rt) rotate(x); 49         else 50         { 51             if (son(x)==son(y)) rotate(y),rotate(x); 52             else rotate(x), rotate(x); 53         } 54     } 55     pushup(x); 56 } 57 int getkth(int rt,int k) 58 { 59     pushdown(rt); 60     int l = ch[rt][0],r = ch[rt][1]; 61     if (k==siz[l]+1) return rt; 62     else if (k<siz[l]+1) return getkth(l,k); 63     else return getkth(r,k-siz[l]-1); 64 } 65 void reverse(int l,int r) 66 { 67     int tl = getkth(root,l),tr = getkth(root,r+2); 68     splay(tl,0);splay(tr,tl); 69     tag[ch[tr][0]] ^= 1; 70 } 71 void build(int l,int r,int f) 72 { 73     if (l>r) return ; 74     int now = id[l],last = id[f]; 75     if (l==r)  76     { 77         fa[now] = last; 78         siz[now] = 1; 79         if (l<f) ch[last][0] = now; 80         else ch[last][1] = now; 81         return ; 82     } 83     int mid = (l+r)>>1; 84     now = id[mid]; 85     build(l,mid-1,mid); 86     build(mid+1,r,mid); 87     fa[now] = last; 88     pushup(mid); 89     if (mid<f) ch[last][0] = now; 90     else ch[last][1] = now; 91 } 92 int main() 93 { 94     n = read();m = read(); 95     for (int i=1; i<=n+2; ++i) id[i] = ++sz; 96     build(1,n+2,0);root = (n+3)>>1;         97     while (m--) 98     { 99         int x = read(),y = read();100         reverse(x,y);101     }102     for (int i=2; i<=n+1; ++i)103         printf("%d ",getkth(root,i)-1);104     return 0;105 }

 

 

P3391 【模板】文艺平衡树(Splay)