zoukankan      html  css  js  c++  java
  • BZOJ3282:Tree(TCL基础题)

    给定N个点以及每个点的权值,要你处理接下来的M个操作。
    操作有4种。操作从0到3编号。点从1到N编号。
    :后接两个整数(x,y),代表询问从x到y的路径上的点的权值的xor和。
    保证x到y是联通的。
    :后接两个整数(x,y),代表连接x到y,若x到Y已经联通则无需连接。
    :后接两个整数(x,y),代表删除边(x,y),不保证边(x,y)存在。
    :后接两个整数(x,y),代表将点X上的权值变成Y。
    Input
    第1行两个整数,分别为N和M,代表点数和操作数。
    第2行到第N+1行,每行一个整数,整数在[,10]内,代表每个点的权值。
    第N+2行到第N+M+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

    题意:给定N个节点的初始值,现在有M个操作,每次输入opt、x、y,opt情况如下。

            0:输出x到y的路径异或和保证x到y是联通的。
            1:连接x和y,已经连通则忽略。
            2:删除边x和y,如果不连通则忽略。(题目的连通应该还保证了是直接相邻,不然需要记录直接相邻的关系)。
            3:把节点x的值改为y。
    思路:和上一题差不多,仅仅是多了个删边操作。
    #include<cstdio>
    #include<cstdlib>
    #include<iostream>
    #include<algorithm>
    using namespace std;
    const int maxn=500010;
    int val[maxn];
    void read(int &x){
        char c=getchar(); x=0;
        for(;c>'9'||c<'0';c=getchar());
        for(;c<='9'&&c>='0';c=getchar()) x=(x<<3)+(x<<1)+c-'0';
    }
    struct LCT
    {
        int sum[maxn],rev[maxn],ch[maxn][2],fa[maxn],stc[maxn],top;
        int isroot(int x){
            return ch[fa[x]][0]!=x&&ch[fa[x]][1]!=x;
        }
        int get(int x){
            return ch[fa[x]][1]==x;
        }
        void pushdown(int x)
        {
            if(!rev[x]||!x) return ;
            swap(ch[x][0],ch[x][1]);
            if(ch[x][0]) rev[ch[x][0]]^=1; 
            if(ch[x][1]) rev[ch[x][1]]^=1; 
            rev[x]=0;
        }
        void pushup(int x)
        {
            sum[x]=val[x];
            if(ch[x][0]) sum[x]^=sum[ch[x][0]];
            if(ch[x][1]) sum[x]^=sum[ch[x][1]];
        }
        void rotate(int x)
        {
            int old=fa[x],fold=fa[old],opt=get(x);
            if(!isroot(old)) ch[fold][get(old)]=x;
            fa[x]=fold;
            ch[old][opt]=ch[x][opt^1]; fa[ch[old][opt]]=old;
            ch[x][opt^1]=old; fa[old]=x; 
            pushup(old); pushup(x);
        }
        void splay(int x)
        {
            int top=0; stc[++top]=x;
            for(int i=x;!isroot(i);i=fa[i]) stc[++top]=fa[i];
            for(int i=top;i;i--) pushdown(stc[i]);
            for(int f;!isroot(x);rotate(x)){
                if(!isroot(f=fa[x]))
                  rotate(get(x)==get(f)?f:x);
            }        
        }
        void access(int x)
        {
            int rson=0;
            for(;x;rson=x,x=fa[x]){
                splay(x);
                ch[x][1]=rson;
                pushup(x);
            }
        }
        int find(int x){ access(x); splay(x); while(ch[x][0]) x=ch[x][0]; return x;}
        void change(int a,int x){ val[a]=x;  access(a);  splay(a); }
        int query(int x,int y) { make_root(y); access(x);  splay(x); return sum[x]; }
        void make_root(int x) { access(x); splay(x); rev[x]^=1; }
        void link(int x,int y) { make_root(x); fa[x]=y; splay(x); }
        void cut(int x,int y) { make_root(x); access(y); splay(y); fa[x]=ch[y][0]=0; }
    }S;
    int main()
    {
        int N,M,a,b,opt;
        scanf("%d%d",&N,&M);
        for(int i=1;i<=N;i++) read(val[i]);
        while(M--){
            read(opt); read(a); read(b);
            if(opt==0) printf("%d
    ",S.query(a,b));
            if(opt==1) if(S.find(a)!=S.find(b)) S.link(a,b);
            if(opt==2) if(S.find(a)==S.find(b)) S.cut(a,b);
            if(opt==3) S.change(a,b);
        }
        return 0;
    }
  • 相关阅读:
    FastDFS学习总结(2)--Tracker与Storage配置详解
    FastDFS学习总结(1)--FastDFS安装和部署
    Git学习总结(6)——作为一名程序员这些代码托管工具你都知道吗?
    Git学习总结(6)——作为一名程序员这些代码托管工具你都知道吗?
    ActiveMQ学习总结(8)——消息队列设计精要
    ActiveMQ学习总结(8)——消息队列设计精要
    vnc
    Apache HTTP服务器 2.0版本文档
    SSH登录很慢
    source insight技巧
  • 原文地址:https://www.cnblogs.com/hua-dong/p/8696378.html
Copyright © 2011-2022 走看看