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,⋯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
#include<cstdio> #include<algorithm> using namespace std; const int MAXN = 100100; int fa[MAXN],ch[MAXN][2],tag[MAXN],siz[MAXN],data[MAXN]; int Root,tn,n; inline char nc() { static char buf[100000],*p1 = buf,*p2 = buf; return p1==p2&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2) ? EOF : *p1++; } inline int read() { int x = 0,f = 1;char ch = nc(); for (; ch<'0'||ch>'9'; ch = nc()) if (ch=='-') f = -1; for (; ch>='0'&&ch<='9'; ch = nc()) x = x*10+ch-'0'; return x * f; } inline int son(int x) { return x == ch[fa[x]][1]; } inline void pushup(int x) { siz[x] = siz[ch[x][0]] + siz[ch[x][1]] + 1; } inline void pushdown(int x) { if (tag[x]) { tag[ch[x][0]] ^= 1; tag[ch[x][1]] ^= 1; swap(ch[x][0],ch[x][1]); tag[x] = 0; } } inline void rotate(int x) { int y = fa[x],z = fa[y],b = son(x),c = son(y),a = ch[x][!b]; if (z) ch[z][c] = x;else Root = x;fa[x] = z; ch[x][!b] = y;fa[y] = x; ch[y][b] = a;if (a) fa[a] = y; pushup(y);pushup(x); } inline void splay(int x,int rt) { while (fa[x] != rt) { int y = fa[x],z = fa[y]; if (z==rt) rotate(x); else { if (son(x)==son(y)) rotate(y),rotate(x); else rotate(x),rotate(x); } } } inline int getkth(int k) { int p = Root; while (true) { pushdown(p); if (k == siz[ch[p][0]] + 1) return p; if (ch[p][0] && k<=siz[ch[p][0]]) p = ch[p][0]; else { k -= ((ch[p][0] ? siz[ch[p][0]] : 0) + 1); p = ch[p][1]; } } } void Reverse(int l,int r) { int L = getkth(l),R = getkth(r+2); splay(L,0);splay(R,L); tag[ch[R][0]] ^= 1; } int build(int l,int r) { if (l > r) return 0; int mid = (l + r) >> 1; int t = build(l,mid-1); ch[mid][0] = t;fa[t] = mid; t = build(mid+1,r); ch[mid][1] = t;fa[t] = mid; pushup(mid); return mid; } void Print(int x) { if (!x) return; pushdown(x); Print(ch[x][0]); if (x > 1 && x < n+2) printf("%d ",x-1); Print(ch[x][1]); } int main() { n = read(); Root = build(1,n+2); /*for(int i=1;i<=n+2;i++) { siz[i] = n+3-i; fa[i] = i-1; ch[i][1] = i+1; } ch[n+2][1]=0,Root=1;*/ int m = read(); while (m--) { int a = read(),b = read(); Reverse(a,b); } Print(Root); return 0; }
- P3391 【模板】文艺平衡树(Splay)
- 洛谷 P3391 【模板】文艺平衡树(Splay)
- P3391 【模板】文艺平衡树(Splay)
- P3391 【模板】文艺平衡树(Splay)
- P3391 【模板】文艺平衡树(Splay)
- luogu #3391 【模板】文艺平衡树(splay)
- 洛谷P3391 【模板】文艺平衡树(Splay)(FHQ Treap)
- BZOJ3323 文艺平衡树 (splay 绿色无毒模板)
- 洛谷.3391.[模板]文艺平衡树(Splay)
- 洛谷P3391 【模板】文艺平衡树(Splay)
- 【洛谷 P3391】【模板】文艺平衡树 --- 区间翻转(splay)
- 【bzoj 3223】文艺平衡树(splay模板)
- bzoj 3223: Tyvj 1729 文艺平衡树(splay 模板题 区间翻转)
- 【模板】文艺平衡树(Splay)
- bzoj3223[Tyvj 1729] 文艺平衡树(splay模板题:区间翻转)
- splay 新模板 【bzoj3223】 文艺平衡树
- 【BZOJ 3223】 文艺平衡树 (splay 板子)
- splay反转-P3391 文艺平衡树
- BZOJ3223: Tyvj 1729 文艺平衡树(Splay) (指针版+数组版)
- 洛谷 P3391 文艺平衡树