AcWing
  • 首页
  • 题库
  • 题解
  • 分享
  • 问答
  • 活动
  • 应用
  • 吐槽
  • 登录/注册

AcWing 2539. 动态树

作者: 作者的头像   dys ,  2021-01-18 22:45:42 ,  阅读 11


0


#include<iostream>
#include<algorithm>
#include<cstring>
#include<cstdio>
using namespace std;
int n,m;
const int N = 1e5+10;
struct node{
    int s[2],p,v;
    int sum,rev;
}tr[N];
int stk[N];
void pushup(int x){
    tr[x].sum = tr[tr[x].s[0]].sum ^ tr[x].v ^ tr[tr[x].s[1]].sum;
}
void pushrev(int x){
    swap(tr[x].s[0],tr[x].s[1]);
    tr[x].rev ^= 1;
}
void pushdown(int x){
    if(tr[x].rev){
        pushrev(tr[x].s[0]);
        pushrev(tr[x].s[1]);
        tr[x].rev ^= 1;
    }
}
bool isroot(int x){
    return tr[tr[x].p].s[0]!=x&&tr[tr[x].p].s[1]!=x;
}
void rotate(int x){
    int y = tr[x].p,z = tr[y].p;
    int k = tr[y].s[1] == x;
    if(!isroot(y)) 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 top = 0,r = x;
    stk[++top] = r;
    while(!isroot(r)) stk[++top] = r = tr[r].p;
    while(top) pushdown(stk[top--]);
    while(!isroot(x)){
        int y = tr[x].p,z = tr[y].p;
        if(!isroot(y))
            if((tr[y].s[1] == x)^(tr[z].s[1] == y)) rotate(x);
            else rotate(y);
        rotate(x);
    }
}
void access(int x){
    int z = x;
    for(int y = 0;x;y = x,x = tr[x].p){
        splay(x);
        tr[x].s[1] = y;
        pushup(x);
    }
    splay(z);
}
void makeroot(int x){
    access(x);
    pushrev(x);
}
int findroot(int x){
    access(x);
    while(tr[x].s[0]) pushdown(x),x = tr[x].s[0];
    splay(x);
    return x;
}
void split(int x,int y){
    makeroot(x);
    access(y);
}
void link(int x,int y){
    makeroot(x);
    if(findroot(y) != x) tr[x].p = y;
}
void cut(int x,int y){
    makeroot(x);
    if(findroot(y) == x && tr[y].p == x && !tr[y].s[0]){
        tr[x].s[1] = tr[y].p = 0;
        pushup(x);
    }
}
int main(){
    cin >> n >> m;
    for(int i=1;i<=n;i++) cin >> tr[i].v;
    int op,x,y,w;
    while(m--){
        cin >> op;
        if(op == 0){
            cin >> x >> y;
            split(x,y);
            cout<< tr[y].sum <<endl;
        }else if(op == 1){
            cin >> x >> y;
            link(x,y);
        }else if(op == 2){
            cin >> x >> y;
            cut(x,y);
        }else{
            cin >> x >> w;
            splay(x);
            tr[x].v = w;
            pushup(x);
        }
    }
    return 0;
}

0 评论

你确定删除吗?

© 2018-2021 AcWing 版权所有  |  京ICP备17053197号-1
联系我们  |  常见问题
AcWing
请输入登录信息
更多登录方式: 微信图标 qq图标
请输入绑定的邮箱地址
请输入注册信息