码迷,mamicode.com
首页 > 其他好文 > 详细

luogu3690 【模板】Link Cut Tree (动态树)

时间:2018-04-11 15:44:09      阅读:124      评论:0      收藏:0      [点我收藏+]

标签:std   for   net   str   access   bool   i++   rev   span   

参考therethere

#include <iostream>
#include <cstdio>
using namespace std;
int n, m, val[300005], ch[300005][2], sum[300005], fa[300005], uu, vv, opt;
int rev[300005];
void pushDown(int x){
    if(rev[x]){
        swap(ch[x][0], ch[x][1]);
        rev[ch[x][0]] ^= 1;
        rev[ch[x][1]] ^= 1;
        rev[x] = 0;
    }
}
bool isRoot(int x){
    return ch[fa[x]][0]!=x && ch[fa[x]][1]!=x;
}
void xf(int x){
    if(!isRoot(x))  xf(fa[x]);
    pushDown(x);
}
bool getW(int x){
    return ch[fa[x]][1]==x;
}
void upd(int x){
    sum[x] = sum[ch[x][0]] ^ sum[ch[x][1]] ^ val[x];
}
void rotate(int x){
    int old=fa[x], oldf=fa[old], w=getW(x);
    if(!isRoot(old))    ch[oldf][ch[oldf][1]==old] = x;
    ch[old][w] = ch[x][w^1]; ch[x][w^1] = old; 
    fa[ch[x][w^1]] = x; fa[ch[old][w]] = old; fa[x] = oldf;
    upd(old); upd(x);
}
void splay(int x){
    xf(x);
    while(!isRoot(x)){
        int f=fa[x];
        if(!isRoot(f))  rotate(getW(x)==getW(f)?f:x);
        rotate(x);
    }
}
void access(int x){
    int y=0;
    while(x){
        splay(x);
        ch[x][1] = y;
        upd(x);
        y = x;
        x = fa[x];
    }
}
void makeRoot(int x){
    access(x);
    splay(x);
    rev[x] ^= 1;
}
int query(int u, int v){
    makeRoot(u);
    access(v);
    splay(v);
    return sum[v];
}
int findRoot(int x){
    access(x);
    splay(x);
    while(ch[x][0])
        x = ch[x][0];
    splay(x);//谜之降低常数
    return x;
}
void link(int u, int v){
    makeRoot(u);
    fa[u] = v;
}
void cut(int u, int v){
    makeRoot(u);
    access(v);
    splay(v);
    if(ch[u][0] || ch[u][1] || fa[u]!=v || ch[v][getW(u)^1])    return ;
    ch[v][0] = fa[u] = 0;
}
void change(int u, int v){
    val[u] = v;
    access(u);
    splay(u);
}
int main(){
    cin>>n>>m;
    for(int i=1; i<=n; i++)
        scanf("%d", &val[i]);
    while(m--){
        scanf("%d %d %d", &opt, &uu, &vv);
        if(opt==0)  printf("%d\n", query(uu, vv));
        else if(opt==1 && findRoot(uu)!=findRoot(vv))
            link(uu, vv);
        else if(opt==2 && findRoot(uu)==findRoot(vv))
            cut(uu, vv);
        else if(opt==3) change(uu, vv);
    }
    return 0;
}

luogu3690 【模板】Link Cut Tree (动态树)

标签:std   for   net   str   access   bool   i++   rev   span   

原文地址:https://www.cnblogs.com/poorpool/p/8794618.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!