【bzoj3223】Tyvj 1729 文艺平衡树
题目描述:
您需要写一种数据结构(可参考题目标题),来维护一个有序数列,其中需要提供以下操作:翻转一个区间,例如原有序序列是5 4 3 2 1,翻转区间是[2,4]的话,结果是5 2 3 4 1
输入:
第一行为n,m n表示初始序列有n个数,这个序列依次是(1,2……n-1,n) m表示翻转操作次数
接下来m行每行两个数[l,r] 数据保证 1<=l<=r<=n
输出:
输出一行n个数字,表示原始序列经过m次变换后的结果
样例输入:
5 3
1 3
1 3
1 4
样例输出:
4 3 2 1 5
数据范围:
N,M<=100000
题解:
直接splay,打个rev标记就好了。
代码:
#include <cstdio> #include <cstring> #include <algorithm> #include <cmath> #ifdef WIN32 #define LL "%I64d" #else #define LL "%lld" #endif #ifdef CT #define debug(...) printf(__VA_ARGS__) #else #define debug(...) #endif #define R register #define getc() (S==T&&(T=(S=B)+fread(B,1,1<<15,stdin),S==T)?EOF:*S++) #define gmax(_a, _b) ((_a) > (_b) ? (_a) : (_b)) #define gmin(_a, _b) ((_a) < (_b) ? (_a) : (_b)) #define cmax(_a, _b) (_a < (_b) ? _a = (_b) : 0) #define cmin(_a, _b) (_a > (_b) ? _a = (_b) : 0) char B[1<<15],*S=B,*T=B; inline int FastIn() { R char ch;R int cnt=0;R bool minus=0; while (ch=getc(),(ch < '0' || ch > '9') && ch != '-') ; ch == '-' ?minus=1:cnt=ch-'0'; while (ch=getc(),ch >= '0' && ch <= '9') cnt = cnt * 10 + ch - '0'; return minus?-cnt:cnt; } #define maxn 100010 bool rev[maxn]; int fa[maxn] , ch[maxn][2] , size[maxn] , root , n; inline void update (R int x) { R int ls = ch[x][0] , rs = ch[x][1]; size[x] = size[ls] + size[rs] + 1; } void Build (R int l , R int r , R int rt) { if (l > r) return ; R int mid = (l + r) >> 1; fa[mid] = rt; if (mid < rt) ch[rt][0] = mid; else ch[rt][1] = mid; Build(l , mid-1 , mid); Build(mid+1 , r , mid); update(mid); } inline void pushdown (R int x) { R int ls = ch[x][0] , rs = ch[x][1]; if (rev[x]) { if (ls) rev[ls] ^= 1 ; if (rs) rev[rs] ^= 1 ; ch[x][0] = rs ; ch[x][1] = ls; rev[x] = 0; } } inline void rotate(R int x) { R int f = fa[x] , gf = fa[f] , d = (ch[f][1] == x); if (f==root) root = x , ch [0][0] = x; (ch[f][d] = ch[x][d ^ 1]) >0 ? fa[ch[f][d]] = f : 0; (fa[x] = gf )> 0 ? ch[gf][ch[gf][1]==f] = x : 0; fa[ch[x][d^1] = f] = x; update (f); } inline void splay(R int x , R int rt) { while (fa[x]!=rt) { R int f = fa[x] , gf = fa[f]; if (gf != rt) rotate ( (ch[gf][1] == f) ^ (ch[f][1] == x) ? x : f ); rotate (x); } update(x); } int find(R int x , R int rank) { if (rev[x]) pushdown(x); R int ls = ch[x][0] , rs = ch[x][1] ,lsize = size[ls]; if (lsize+1 == rank) return x; if (lsize >= rank ) return find(ls , rank); else return find(rs , rank -lsize -1); } inline int prepare (R int l,R int r) { R int x = find (root ,l-1 ); splay(x , 0); x = find(root , r+1) ; splay(x , root); return ch[x][0]; } inline void rever(R int l,R int r) { R int x = prepare (l,r); rev[x] ^= 1; pushdown(x); } inline void print(R int x) { if (!x) return; if (rev[x]) pushdown(x); R int ls = ch[x][0] , rs = ch[x][1]; print(ls); if (x != 1 && x!=n )printf("%d ",x -1 ); print(rs); } int main() { n = FastIn()+2 ;R int m = FastIn(); Build(1 , n , 0); root = ( 1 + n ) >> 1; for (; m ; m--) { R int l = FastIn() + 1 , r = FastIn() + 1; rever( l , r ); } splay(1,0); print(root); return 0; }