C04【模板】Splay P3391 文艺平衡树
视频链接:262【模板】Splay P3391 文艺平衡树_哔哩哔哩_bilibili
#include <iostream> #include <algorithm> using namespace std; const int N=100010; int n, m; struct node{ int s[2], p, v; int size, tag;//懒标记 void init(int p1,int v1){ p=p1; v=v1; size=1; } }tr[N]; int root,idx; void pushup(int x){ tr[x].size=tr[tr[x].s[0]].size +tr[tr[x].s[1]].size+1; } void pushdown(int x){ //下传 if(tr[x].tag){ swap(tr[x].s[0],tr[x].s[1]); tr[tr[x].s[0]].tag ^= 1; tr[tr[x].s[1]].tag ^= 1; tr[x].tag = 0; } } void rotate(int x){ int y=tr[x].p, z=tr[y].p; int k = tr[y].s[1]==x; tr[z].s[tr[z].s[1]==y] =x; tr[x].p = z; tr[y].s[k] = tr[x].s[k^1]; tr[tr[x].s[k^1]].p = y; tr[x].s[k^1] = y; tr[y].p = x; pushup(y), pushup(x); } void splay(int x, int k){ while(tr[x].p!=k){ int y=tr[x].p, z=tr[y].p; if(z!=k) // 折转底,直转中 (tr[y].s[0]==x)^(tr[z].s[0]==y) ? rotate(x) : rotate(y); rotate(x); } if(k==0) root = x; } void insert(int v){ int x=root, p=0; while(x)p=x,x=tr[x].s[v>tr[x].v]; x = ++idx; tr[p].s[v>tr[p].v]=x; tr[x].init(p,v); splay(x, 0); } int get_k(int k){//返回第k个节点编号 int x=root; while(1){ pushdown(x); int y=tr[x].s[0]; if(tr[y].size+1<k) k -= tr[y].size+1, x = tr[x].s[1]; else if(tr[y].size>=k) x=y; else return x; } } void output(int x){ //中序遍历输出 pushdown(x); if(tr[x].s[0]) output(tr[x].s[0]); if(tr[x].v >= 1 && tr[x].v <= n) printf("%d ", tr[x].v); if(tr[x].s[1]) output(tr[x].s[1]); } int main(){ insert(-1e6);insert(1e6);//哨兵 scanf("%d%d", &n, &m); for(int i=1;i<=n;i++)insert(i); while(m--){ // 把[l,r]夹挤到l-1和r+1之间 int l, r; scanf("%d%d", &l, &r); l=get_k(l), r=get_k(r+2); splay(l, 0); splay(r, l); tr[tr[r].s[0]].tag ^= 1; } output(root); return 0; }