洛谷 P3391【模板】文艺平衡树(Splay) 发表于 2018-05-14 | 分类于 数据结构 题目https://www.luogu.org/problemnew/show/P3391 题意写一种数据结构,实现区间翻转的操作 题解splay打个lazy标记就好了 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132#include <cstdio>#include <algorithm>using namespace std;struct node{ int ch[2]; int ff,cnt,sz,val,lazy;};const int MAXN = 1e5+10;int root,n,tot,m;node t[MAXN];void PushUp(int x){ t[x].sz = t[t[x].ch[0]].sz + t[t[x].ch[1]].sz + t[x].cnt;}void PushDown(int x){ if(t[x].lazy) { t[t[x].ch[0]].lazy ^= 1; t[t[x].ch[1]].lazy ^= 1; swap(t[x].ch[0], t[x].ch[1]); t[x].lazy ^= 1; }}void Rotate(int x){ int y = t[x].ff; int z = t[y].ff; int k = (t[y].ch[1]==x); t[z].ch[t[z].ch[1]==y]=x; t[x].ff = z; t[y].ch[k] = t[x].ch[k^1]; t[t[x].ch[k^1]].ff = y; t[x].ch[k^1] = y; t[y].ff = x; PushUp(y); PushUp(x);}void Splay(int x, int goal){ while(t[x].ff != goal) { int y = t[x].ff; int z = t[y].ff; if(z != goal) (t[z].ch[0]==y)^(t[y].ch[0]==x)?Rotate(x):Rotate(y); Rotate(x); } if(goal == 0) root = x;}void Insert(int x){ int u = root, ff = 0; while(u && t[u].val != x) { ff = u; t[u].sz++; u = t[u].ch[x > t[u].val]; } if(u) t[u].cnt++, t[u].sz++; else { u = ++tot; if(ff) t[ff].ch[x > t[ff].val] = u; t[u].ch[0] = t[u].ch[1] = 0; t[tot].ff = ff; t[tot].val = x; t[tot].sz = t[tot].cnt = 1; t[tot].lazy = 0; } Splay(u, 0);}int KTh(int k){ int u = root; while(true) { PushDown(u); if(t[t[u].ch[0]].sz + 1 < k) { k = k - t[t[u].ch[0]].sz - 1; u = t[u].ch[1]; } else if(t[t[u].ch[0]].sz+1 > k) u = t[u].ch[0]; else return u; }}void solve(int l, int r){ l = KTh(l); r = KTh(r+2); Splay(l, 0); Splay(r, l); t[t[t[root].ch[1]].ch[0]].lazy ^= 1;}void Output(int x){ PushDown(x); if(t[x].ch[0]) Output(t[x].ch[0]); if(t[x].val > 1 && t[x].val < n+2) printf("%d ",t[x].val-1); if(t[x].ch[1]) Output(t[x].ch[1]);}int main(){ scanf("%d %d", &n, &m); for(int i = 1; i <= n+2; ++i) Insert(i); int l,r; while(m--) { scanf("%d %d",&l, &r); solve(l, r); } Output(root); return 0;}