splay 动态维护dfs序

来源:互联网 发布:bpa软件下载 编辑:程序博客网 时间:2024/05/17 04:35

Gty的游戏

调程经验:
1.splay 写的时候小心,加入时注意splay到根
2.连接儿子时,别忘记连接父亲的边.
3.调试时可以先封装好,输入特定信息调试
4.splay维护序列是提取右端点的左儿子

知识点:1.欧拉序维护:栈.
2.这种题,就想到套路博弈论,阶梯博弈的技巧

骗分程序并列时间rank1.

%:pragma GCC optimize(2)#include <cstdio>#include <iostream>#include <cstring>#include <cassert>using namespace std;const int N = 2e5 + 5;const int M = N * 2;int fir[N] , ne[M] , to[M] , cnt , stk[N] , ch[N][2] , w[N][2] , dep[N] , x , y , z  , num[N] , ty , t , fa[N] , rt , top , pos[N][2] , n , m , how[N] , d[N];bool dir(int x) {    return (ch[fa[x]][1] == x);}int abs(int x) {    return (x < 0) ? -x : x;}#define lc ch[no][0]#define rc ch[no][1]inline void add(int x , int y) {    ne[++ cnt] = fir[x]; fir[x] = cnt; to[cnt] = y;}inline void link(int x , int y) {    add(x , y); add(y , x);}void up(int no) {    w[no][0] = w[no][1] = 0;    if(lc) w[no][0] ^= w[lc][0] , w[no][1] ^= w[lc][1];    if(rc) w[no][0] ^= w[rc][0] , w[no][1] ^= w[rc][1];    w[no][d[no]] ^= how[no];}void rotate(int x) {    bool D = dir(x) , DF = dir(fa[x]);    int F = fa[x]; int GF = fa[F];    if(GF) ch[GF][DF] = x; fa[x] = GF; if(ch[x][!D])fa[ch[x][!D]] = F; fa[F] = x;    ch[F][D] = ch[x][!D]; ch[x][!D] = F;    up(F); up(x);}void splay(int x , int f) {    while(fa[fa[x]] != f && fa[x] != f) {        (dir(fa[x]) ^ dir(x)) ? (rotate(x) , rotate(x)) : (rotate(fa[x]) , rotate(x));    }    if(fa[x] != f) rotate(x); if(!f)rt = x;}#define Foreachson(i , x) for(int i = fir[x];i;i = ne[i])inline void dfs(int x , int f) {    stk[++ top] = x; dep[x] = (dep[f] + 1) % 2;    int V;    Foreachson(i , x) {        V = to[i]; if(V == f) continue;        dfs(V , x);stk[++ top] = -V;    }}int build(int l , int r) {    if(l > r) return 0;    int mid = (l + r) >> 1 , dir = 0 , ls , rs;    if(stk[mid] < 0) dir = 1; else how[mid] = num[stk[mid]]; pos[(int)abs(stk[mid])][dir] = mid; d[mid] = dep[(int)abs(stk[mid])];    ls = build(l , mid - 1) , rs = build(mid + 1 , r);    ch[mid][0] = ls; ch[mid][1] =  rs; if(ls) fa[ls] = mid; if(rs) fa[rs] = mid; up(mid);    return mid;}void insert(int x , int y , int z) {    splay(pos[x][0] , 0); assert(pos[x][0] == rt);    int now = ch[rt][1]; while(ch[now][0]) now = ch[now][0];    int beg = ++ top , end = ++ top;    ch[now][0] = beg; fa[beg] = now; ch[beg][1] = end; fa[end] = beg; pos[y][0] = beg; pos[y][1] = end;    d[pos[y][0]] = d[pos[y][1]] = dep[x] ^ 1; dep[y] = dep[x] ^ 1; how[pos[y][0]] = z % m; up(end); up(beg); up(now);     splay(end , 0);}int main(void) {    scanf("%d%d" , &n , &m); m ++;for(int i = 1;i <= n;i ++) scanf("%d" , &num[i]) , num[i] %= m;    for(int i = 1;i < n;i ++) scanf("%d%d" , &x , &y) , link(x , y);    dfs(1 , 0); stk[++ top] = -1;rt = build(1 , top);    int sum = 0;    for(scanf("%d" , &t);t--;) {        scanf("%d%d" ,&ty, &x); x ^= sum;        if(ty == 1) {            splay(pos[x][0] , 0);            splay(pos[x][1] , pos[x][0]);            if(w[ch[pos[x][1]][0]][dep[x] ^ 1]) {                puts("MeiZ");                sum ++;            }            else puts("GTY");        }        else if(ty == 2) {            scanf("%d" , &y); y ^= sum; y %= m;            splay(pos[x][0] , 0); how[pos[x][0]] = y; up(pos[x][0]);        }        else {            scanf("%d%d" , &y , &z); y ^= sum; z ^= sum; z %= m;            insert(x , y , z);        }    }}
原创粉丝点击