zoukankan      html  css  js  c++  java
  • BZOJ3282: Tree

    BZOJ3282: Tree

    Description

    给定N个点以及每个点的权值,要你处理接下来的M个操作。
    操作有4种。操作从0到3编号。点从1到N编号。
    0:后接两个整数(x,y),代表询问从x到y的路径上的点的权值的xor和。
    保证x到y是联通的。
    1:后接两个整数(x,y),代表连接x到y,若x到Y已经联通则无需连接。
    2:后接两个整数(x,y),代表删除边(x,y),不保证边(x,y)存在。
    3:后接两个整数(x,y),代表将点X上的权值变成Y。

    Input

    第1行两个整数,分别为N和M,代表点数和操作数。
    第2行到第N+1行,每行一个整数,整数在[1,10^9]内,代表每个点的权值。
    第N+2行到第N+M+1行,每行三个整数,分别代表操作类型和操作所需的量。
    1<=N,M<=300000

    Output

    对于每一个0号操作,你须输出X到Y的路径上点权的Xor和。

    Sample Input

    3 3
    1
    2
    3
    1 1 2
    0 1 2
    0 1 1

    Sample Output

    3
    1
    题解Here!
    这个算是LCT板子题了吧。。。
    附代码:
    #include<iostream>
    #include<algorithm>
    #include<cstdio>
    #define MAXN 300010
    using namespace std;
    int n,m,val[MAXN];
    int top=0,stack[MAXN];
    struct Link_Cut_Tree{
        int son[2];
        int f,v,flag;
    }a[MAXN];
    inline int read(){
        int date=0,w=1;char c=0;
        while(c<'0'||c>'9'){if(c=='-')w=-1;c=getchar();}
        while(c>='0'&&c<='9'){date=date*10+c-'0';c=getchar();}
        return date*w;
    }
    inline bool isroot(int rt){
        return a[a[rt].f].son[0]!=rt&&a[a[rt].f].son[1]!=rt;
    }
    inline void pushup(int rt){
        if(!rt)return;
        a[rt].v=val[rt]^a[a[rt].son[0]].v^a[a[rt].son[1]].v;
    }
    inline void pushdown(int rt){
        if(!rt||!a[rt].flag)return;
        a[a[rt].son[0]].flag^=1;a[a[rt].son[1]].flag^=1;a[rt].flag^=1;
        swap(a[rt].son[0],a[rt].son[1]);
    }
    inline void turn(int rt){
        int x=a[rt].f,y=a[x].f,k=a[x].son[0]==rt?1:0;
        if(!isroot(x)){
            if(a[y].son[0]==x)a[y].son[0]=rt;
            else a[y].son[1]=rt;
        }
        a[rt].f=y;a[x].f=rt;a[a[rt].son[k]].f=x;
        a[x].son[k^1]=a[rt].son[k];a[rt].son[k]=x;
        pushup(x);pushup(rt);
    }
    void splay(int rt){
        top=0;
        stack[++top]=rt;
        for(int i=rt;!isroot(i);i=a[i].f)stack[++top]=a[i].f;
        while(top)pushdown(stack[top--]);
        while(!isroot(rt)){
            int x=a[rt].f,y=a[x].f;
            if(!isroot(x)){
                if((a[y].son[0]==x)^(a[x].son[0]==rt))turn(rt);
                else turn(x);
            }
            turn(rt);
        }
    }
    inline void access(int rt){
        for(int i=0;rt;i=rt,rt=a[rt].f){
            splay(rt);
            a[rt].son[1]=i;
            pushup(rt);
        }
    }
    inline void makeroot(int rt){access(rt);splay(rt);a[rt].flag^=1;}
    int find(int rt){
        access(rt);splay(rt);
        while(a[rt].son[0])rt=a[rt].son[0];
        return rt;
    }
    inline void split(int x,int y){makeroot(x);access(y);splay(y);}
    inline void link(int x,int y){makeroot(x);a[x].f=y;}
    inline void cut(int x,int y){
        split(x,y);
        if(a[y].son[0]==x&&a[x].f==y&&!a[x].son[1])a[y].son[0]=a[x].f=0;
    }
    inline int query(int x,int y){split(x,y);return a[y].v;}
    void work(){
        int f,x,y;
        while(m--){
            f=read();x=read();y=read();
            switch(f){
                case 0:printf("%d
    ",query(x,y));break;
                case 1:{
                    int fx=find(x),fy=find(y);
                    if(fx!=fy)link(x,y);
                    break;
                }
                case 2:{
                    int fx=find(x),fy=find(y);
                    if(fx==fy)cut(x,y);
                    break;
                }
                case 3:access(x);splay(x);val[x]=y;pushup(x);break;
            }
        }
    }
    void init(){
        n=read();m=read();
        for(int i=1;i<=n;i++)val[i]=read();
    }
    int main(){
        init();
        work();
        return 0;
    }
    
  • 相关阅读:
    error和exception有什么区别?
    金额转换,阿拉伯数字的金额转换成中国传统的形式如:(¥1011)->(一千零一拾一元整)输出?
    HTTP请求的GET与POST方式的区别
    解释一下什么是servlet?
    参数Parameters、变量Variables
    数据库事务的四大隔离级别以及处理的问题
    redis安装
    CVB生命周期(APIView源码解析)
    前端页面渲染机制
    Django基础之request
  • 原文地址:https://www.cnblogs.com/Yangrui-Blog/p/9373753.html
Copyright © 2011-2022 走看看