3223: Tyvj 1729 文艺平衡树
Time Limit: 10 Sec Memory Limit: 128 MB Submit: 5356 Solved: 3163 [Submit][Status][Discuss]
Description
您需要写一种数据结构(可参考题目标题),来维护一个有序数列,其中需要提供以下操作:翻转一个区间,例如原有序序列是5 4 3 2 1,翻转区间是[2,4]的话,结果是5 2 3 4 1
Input
第一行为n,m n表示初始序列有n个数,这个序列依次是(1,2……n-1,n) m表示翻转操作次数 接下来m行每行两个数[l,r] 数据保证 1<=l<=r<=n
Output
输出一行n个数字,表示原始序列经过m次变换后的结果
Sample Input
5 3
1 3
1 3
1 4
Sample Output
4 3 2 1 5
对区间维护splay,翻转打标记即可
#include <cstdio> #include <algorithm> using namespace std; const int maxn = 100000 + 10; int n, m; int root, fa[maxn], son[maxn][2], siz[maxn], val[maxn]; bool tag[maxn] = {false}; int num[maxn], cnt = 0; inline void pushup(int x){ siz[x] = siz[son[x][0]] + siz[son[x][1]] + 1; } inline void rotate(int x){ int y = fa[x], p = son[y][0] == x; son[y][!p] = son[x][p]; fa[son[x][p]] = y; fa[x] = fa[y]; if(fa[x]) son[fa[x]][son[fa[x]][1] == y] = x; son[x][p] = y; fa[y] = x; pushup(y); } inline void splay(int x, int t){ int y, z; while(fa[x] != t){ if(fa[fa[x]] == t) rotate(x); else{ y = fa[x]; z = fa[y]; if(son[y][0] == x ^ son[z][0] == y) rotate(x); else rotate(y); rotate(x); } } pushup(x); if(!t) root = x; } inline void pushdown(int x){ if(tag[x]){ swap(son[x][0], son[x][1]); tag[son[x][0]] ^= 1; tag[son[x][1]] ^= 1; tag[x] = 0; } } inline void find(int kth, int t){ int x = root, tmp; while(x){ pushdown(x); tmp = siz[son[x][0]]; if(kth == tmp + 1){ splay(x, t); return; } if(kth > tmp + 1){ kth -= tmp + 1; x = son[x][1]; } else x = son[x][0]; } } int build(int l, int r){ if(l > r) return 0; int now = ++cnt, mid = l + r >> 1; val[now] = num[mid]; siz[now] = 1; son[now][0] = build(l, mid - 1); if(son[now][0]) fa[son[now][0]] = now; son[now][1] = build(mid + 1, r); if(son[now][1]) fa[son[now][1]] = now; pushup(now); return now; } void init(){ scanf("%d %d", &n, &m); siz[0] = son[0][0] = son[0][1] = 0; num[1] = num[n + 2] = 66662333; for(int i = 1; i <= n; i++) num[i + 1] = i; root = build(1, n + 2); } void zx(int x){ if(!x) return; pushdown(x); zx(son[x][0]); printf("%d ", val[x]); zx(son[x][1]); } void work(){ for(int l, r, i = 1; i <= m; i++){ scanf("%d %d", &l, &r); find(l, 0); find(r + 2, root); tag[son[son[root][1]][0]] ^= 1; } find(1, 0); find(n + 2, root); zx(son[son[root][1]][0]); } int main(){ init(); work(); return 0; }
时间: 2024-10-07 09:09:44