2019牛客国庆集训派对day1 K题 双向链表练习题 splay区间翻转
解法:
先建n颗平衡树,合并的时候将a中最右的结点翻转到根节点,b中最左的结点翻转到根节点,对合并后的根节点进行标记。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include <bits/stdc++.h> using namespace std; #define ls(p) p << 1 #define rs(p) p << 1 | 1 const int M = 1e5 + 10; int n, m, cnt; int rt[M]; struct node{ int fa, ch[2], val, cnt, sz, lazy; }spl[M]; bool ident(int x, int f) { return spl[f].ch[1] == x; } void connect(int x, int f, int s){ spl[f].ch[s] = x; spl[x].fa = f; } void update(int now) { spl[now].sz = spl[spl[now].ch[0]].sz + spl[spl[now].ch[1]].sz + spl[now].cnt; } void push_down(int now) { if(!spl[now].lazy) return; swap(spl[now].ch[0], spl[now].ch[1]); spl[spl[now].ch[0]].lazy ^= 1; spl[spl[now].ch[1]].lazy ^= 1; spl[now].lazy = 0; } void rotate(int x) { int f = spl[x].fa, ff = spl[f].fa, k = ident(x, f); connect(spl[x].ch[k ^ 1], f, k); connect(x, ff, ident(f, ff)); connect(f, x, k ^ 1); update(f), update(x); } void splaying(int p, int x, int top) { if(!top) rt[p] = x; //printf("top = %d\n", top); while(spl[x].fa != top) { //if(num <= 5) num++, printf("\n%d %d\n", x, top); int f = spl[x].fa, ff = spl[f].fa; if(ff != top) ident(f, ff) ^ ident(x, f) ? rotate(x) : rotate(f); rotate(x); } } int find_r(int now) { push_down(now); while(spl[now].ch[1]) { now = spl[now].ch[1]; push_down(now); } return now; } int find_l(int now) { push_down(now); while(spl[now].ch[0]) { now = spl[now].ch[0]; push_down(now); } return now; } void newnode(int now, int val) { spl[now].val = val; spl[now].sz = 1; spl[now].cnt = 1; spl[now].ch[0] = 0; spl[now].ch[1] = 0; spl[now].fa = 0; spl[now].lazy = 0; } void work(){ for(int i = 1; i <= n; i++) { rt[i] = i; newnode(i, i); } for(int i = 1; i <= m; i++) { int u, v; scanf("%d%d", &u, &v); if(!rt[u]) { if(rt[v]){ rt[u] = rt[v]; spl[rt[u]].lazy ^= 1; rt[v] = 0; } } else if(!rt[v]) { spl[rt[u]].lazy ^= 1; } else { int r = find_r(rt[u]); splaying(u, r, 0); //printf("1 \n"); int l = find_l(rt[v]); //printf("3\n"); splaying(v, l, 0); //printf("2\n"); connect(l, r, 1); spl[rt[u]].lazy ^= 1; rt[v] = 0; update(rt[u]); } } } void out(int now){ if(!now) return; push_down(now); out(spl[now].ch[0]); printf("%d ", spl[now].val); out(spl[now].ch[1]); } int main(){ while(~scanf("%d%d", &n, &m)){ cnt = 0; work(); printf("%d ", spl[rt[1]].sz); if(spl[rt[1]].sz) out(rt[1]); printf("\n"); } return 0; } /* 999 5 99 8 8 99 99 8 7 99 1 7 */ /* 999 5 1 3 1 4 1 5 1 6 1 7 */