【bzoj2002】弹飞绵羊

来源:互联网 发布:多功能网络性能测试仪 编辑:程序博客网 时间:2024/04/28 09:45

Lct裸题

给出一棵树,有修改及询问,修改操作为修改一个节点的父亲,询问一个节点到根的点数。

询问及修改前只需Access一遍即可。

#include <iostream>#include <cstdio>#include <cstring>#include <string>#include <algorithm>#include <cmath>#define Rep(i, x, y) for (int i = x; i <= y; i ++)#define RepE(i, x) for (int i = pos[x]; i; i = g[i].nex)#define lc t[x].ch[0]#define rc t[x].ch[1]#define Lc t[lc]#define Rc t[rc]#define tp t[x].par#define Tp t[t[x].par]using namespace std;typedef long long LL;const int N = 200005;struct arr { int ch[2], par, sz; } t[N];bool rt[N];int n, m, q;void Upd(int x) { t[x].sz = Lc.sz + Rc.sz + 1; }void Sc(int x, int y, bool f) { t[y].ch[f] = x, tp = y; }void Rot(int x, bool f) {    int y = tp;    Sc(t[x].ch[f], y, !f);    tp = Tp.par; Sc(y, x, f);    if (rt[y]) rt[y] = 0, rt[x] = 1;    else Tp.ch[Tp.ch[1] == y] = x;    Upd(y);}void Splay(int x) {    while (!rt[x]) {        if (rt[tp]) { Rot(x, Tp.ch[0] == x); break; }        bool f = (t[Tp.par].ch[1] == tp);        if (Tp.ch[f] == x) Rot(tp, !f), Rot(x, !f);        else Rot(x, f), Rot(x, !f);     } Upd(x);}void Access(int x) {    Splay(x);    rt[rc] = 1, rc = 0;    while (tp) { //cout << 1;        int y = tp;        Splay(y);        rt[t[y].ch[1]] = 1;        t[y].ch[1] = x;        rt[x] = 0;        x = tp, Upd(x);    }}int main(){    cin >> n;    Rep(i, 1, n) {        int x;        scanf ("%d", &x), x = min(x+i, n+1);        t[i].par = x, rt[i] = 1, t[x].sz = 1;    }    rt[n+1] = 1, t[n+1].sz = 1;    cin >> q;    Rep(i, 1, q) {        int type, x;        scanf ("%d%d", &type, &x), x ++;        if (type == 1) {            Access(x); Splay(x);            printf ("%d\n", t[x].sz - 1);        } else {            int y;            scanf ("%d", &y), y = min(x+y, n+1);            Access(x); Splay(x);            rt[lc] = 1, Lc.par = tp, lc = 0;            t[x].sz = Rc.sz + 1, tp = y;        }    }     return 0;}


0 0
原创粉丝点击