【模板】Splay(區間操作)
阿新 • • 發佈:2018-11-06
這裡的操作是區間翻轉
struct node* null;//注意這個要在主函式中初始化 struct node { node *son[2], *fa; int v; int s; bool tag; node() { son[0] = son[1] = fa = null; tag = 0; } void push_up() { s = son[0]->s + son[1]->s + 1; } void push_down() { if(tag) { swap(son[0], son[1]); son[0]->tag ^= 1; son[1]->tag ^= 1; tag = false; } } }*root; void rotate(node *p) { p->push_down(); node *f = p->fa; node *ff = f->fa; ff->son[f == ff->son[1]] = p; p->fa = ff; bool c = p == f->son[1]; f->son[c] = p->son[!c]; p->son[!c]->fa = f; f->fa = p; p->son[!c] = f; p->push_up(), f->push_up(); } void splay(node *p, node *r = null) { node *f = p->fa, *ff; while(f != r) { ff = f->fa; if(ff != r) { if((p == f->son[1]) ^ (f == ff->son[1]))rotate(p); else rotate(f); } rotate(p); f = p->fa; } if(r == null)root = p; } void build(int n) { root = new node; root->v = 0; node* p =root; for(int i = 1; i <= n + 1; i ++) p->son[1] = new node, p->son[1]->fa = p, p = p->son[1], p->v = i; p->s = 1; splay(p); } node* kth(int k) { node *p = root; while(1) { p->push_down(); if(p->son[0]->s >= k)p = p->son[0]; else if(p->son[0]->s + 1 ==k)return p; else k -= p->son[0]->s + 1, p = p->son[1]; } } void work(int l, int r) { splay(kth(l)); splay(kth(r + 2), root); root->son[1]->son[0]->tag ^= 1; }