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,?n−1,n) m表示翻转操作次数
接下来m行每行两个数 [l,r][l,r] 数据保证 1 \leq l \leq r \leq n1≤l≤r≤n
输出格式:
输出一行n个数字,表示原始序列经过m次变换后的结果
输入输出样例
输入样例#1: 复制
5 3 1 3 1 3 1 4
输出样例#1: 复制
4 3 2 1 5
说明
n, m \leq 100000n,m≤100000
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],data[MAXN]; 8 int Root,tn,n; 9 10 inline char nc() { 11 static char buf[100000],*p1 = buf,*p2 = buf; 12 return p1==p2&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2) ? EOF : *p1++; 13 } 14 inline int read() { 15 int x = 0,f = 1;char ch = nc(); 16 for (; ch<‘0‘||ch>‘9‘; ch = nc()) 17 if (ch==‘-‘) f = -1; 18 for (; ch>=‘0‘&&ch<=‘9‘; ch = nc()) 19 x = x*10+ch-‘0‘; 20 return x * f; 21 } 22 inline int son(int x) { 23 return x == ch[fa[x]][1]; 24 } 25 inline void pushup(int x) { 26 siz[x] = siz[ch[x][0]] + siz[ch[x][1]] + 1; 27 } 28 inline void pushdown(int x) { 29 if (tag[x]) { 30 tag[ch[x][0]] ^= 1; 31 tag[ch[x][1]] ^= 1; 32 swap(ch[x][0],ch[x][1]); 33 tag[x] = 0; 34 } 35 } 36 inline void rotate(int x) { 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 ch[x][!b] = y;fa[y] = x; 40 ch[y][b] = a;if (a) fa[a] = y; 41 pushup(y);pushup(x); 42 } 43 inline void splay(int x,int rt) { 44 while (fa[x] != rt) { 45 int y = fa[x],z = fa[y]; 46 if (z==rt) rotate(x); 47 else { 48 if (son(x)==son(y)) rotate(y),rotate(x); 49 else rotate(x),rotate(x); 50 } 51 } 52 } 53 inline int getkth(int k) { 54 int p = Root; 55 while (true) { 56 pushdown(p); 57 if (k == siz[ch[p][0]] + 1) return p; 58 if (ch[p][0] && k<=siz[ch[p][0]]) p = ch[p][0]; 59 else { 60 k -= ((ch[p][0] ? siz[ch[p][0]] : 0) + 1); 61 p = ch[p][1]; 62 } 63 } 64 } 65 void Reverse(int l,int r) { 66 int L = getkth(l),R = getkth(r+2); 67 splay(L,0);splay(R,L); 68 tag[ch[R][0]] ^= 1; 69 } 70 inline void Connect(int x,int pa,int f) { 71 fa[x] = pa;ch[pa][f] = x; 72 } 73 int build(int l,int r) { 74 if (l > r) return 0; 75 int mid = (l + r) >> 1; 76 int t = build(l,mid-1); 77 ch[mid][0] = t;fa[t] = mid; 78 t = build(mid+1,r); 79 ch[mid][1] = t;fa[t] = mid; 80 pushup(mid); 81 return mid; 82 } 83 void Print(int x) { 84 if (!x) return; 85 pushdown(x); 86 Print(ch[x][0]); 87 if (x > 1 && x < n+2) printf("%d ",x-1); 88 Print(ch[x][1]); 89 } 90 int main() { 91 n = read(); 92 Root = build(1,n+2); 93 /*for(int i=1;i<=n+2;i++) { 94 siz[i] = n+3-i; 95 fa[i] = i-1; 96 ch[i][1] = i+1; 97 } 98 ch[n+2][1]=0,Root=1;*/ 99 int m = read(); 100 while (m--) { 101 int a = read(),b = read(); 102 Reverse(a,b); 103 } 104 Print(Root); 105 return 0; 106 }
时间: 2024-10-16 21:44:23