• AC日记——Dylans loves tree hdu 5274


    Dylans loves tree

    Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)
    Total Submission(s): 1611    Accepted Submission(s): 388


    Problem Description
    Dylans is given a tree with N nodes.

    All nodes have a value A[i] .Nodes on tree is numbered by 1N .

    Then he is given Q questions like that:

    0 x y :change node xs value to y

    1 x y :For all the value in the path from x to y ,do they all appear even times?

    For each ② question,it guarantees that there is at most one value that appears odd times on the path.

    1N,Q100000 , the value A[i]N and A[i]100000
     
    Input
    In the first line there is a test number T .
    (T3 and there is at most one testcase that N>1000 )

    For each testcase:

    In the first line there are two numbers N and Q .

    Then in the next N1 lines there are pairs of (X,Y) that stand for a road from x to y .

    Then in the next line there are N numbers A1..AN stand for value.

    In the next Q lines there are three numbers(opt,x,y) .
     
    Output
    For each question ② in each testcase,if the value all appear even times output "-1",otherwise output the value that appears odd times.
     
    Sample Input
    1 3 2 1 2 2 3 1 1 1 1 1 2 1 1 3
     
    Sample Output
    -1 1
    Hint
    If you want to hack someone,N and Q in your testdata must smaller than 10000,and you shouldn't print any space in each end of the line.
     
    Source
     
     
    思路:
      判断树上路径是否有出现过奇数次的权值;
      数据保证一条路径上最多一个出现奇数次的权值;
      因为x^x=0,0^x=x的性质;
      我们可以用异或和;
      把一条路径的全部权值都异或;
      如果等于0则不存在,否则就输出;
      同时,因为0^0=0;
      所以我们全部的权值都+1;
      然后,输出时再-1;
     
     
    来,上代码:
    #include <cstdio>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    
    #define maxn 100005
    
    using namespace std;
    
    struct TreeNodeType {
        int l,r,dis,mid;
    };
    struct TreeNodeType tree[maxn<<2];
    
    struct EdgeType {
        int v,next;
    };
    struct EdgeType edge[maxn<<1];
    
    int if_z,t,n,q,dis[maxn],dis_[maxn];
    int cnt=0,head[maxn],deep[maxn],f[maxn];
    int top[maxn],size[maxn],flag[maxn];
    
    char Cget;
    
    inline void in(int &now)
    {
        now=0,if_z=1,Cget=getchar();
        while(Cget>'9'||Cget<'0')
        {
            if(Cget=='-') if_z=-1;
            Cget=getchar();
        }
        while(Cget>='0'&&Cget<='9')
        {
            now=now*10+Cget-'0';
            Cget=getchar();
        }
        now*=if_z;
    }
    
    inline void edge_add(int u,int v)
    {
        cnt++;
        edge[cnt].v=v;
        edge[cnt].next=head[u];
        head[u]=cnt;
    }
    
    void search_1(int now,int fa)
    {
        int pos=cnt++;
        deep[now]=deep[fa]+1,f[now]=fa;
        for(int i=head[now];i;i=edge[i].next)
        {
            if(edge[i].v==fa) continue;
            search_1(edge[i].v,now);
        }
        size[now]=cnt-pos;
    }
    
    void search_2(int now,int chain)
    {
        top[now]=chain,flag[now]=++cnt;
        dis[flag[now]]=dis_[now]+1;
        int pos=0;
        for(int i=head[now];i;i=edge[i].next)
        {
            if(edge[i].v==f[now]) continue;
            if(size[edge[i].v]>size[pos]) pos=edge[i].v;
        }
        if(pos==0) return ;
        search_2(pos,chain);
        for(int i=head[now];i;i=edge[i].next)
        {
            if(edge[i].v==pos||edge[i].v==f[now]) continue;
            search_2(edge[i].v,edge[i].v);
        }
    }
    
    inline void tree_up(int now)
    {
        tree[now].dis=tree[now<<1].dis^tree[now<<1|1].dis;
    }
    
    void tree_build(int now,int l,int r)
    {
        tree[now].l=l,tree[now].r=r;
        if(l==r)
        {
            tree[now].dis=dis[l];
            return ;
        }
        tree[now].mid=(l+r)>>1;
        tree_build(now<<1,l,tree[now].mid);
        tree_build(now<<1|1,tree[now].mid+1,r);
        tree_up(now);
    }
    
    void tree_change(int now,int to,int x)
    {
        if(tree[now].l==tree[now].r)
        {
            tree[now].dis=x;
            return ;
        }
        if(to<=tree[now].mid) tree_change(now<<1,to,x);
        else tree_change(now<<1|1,to,x);
        tree_up(now);
    }
    
    int tree_query(int now,int l,int r)
    {
        if(tree[now].l==l&&tree[now].r==r)
        {
            return tree[now].dis;
        }
        if(l>tree[now].mid) return tree_query(now<<1|1,l,r);
        else if(r<=tree[now].mid) return tree_query(now<<1,l,r);
        else return tree_query(now<<1,l,tree[now].mid)^tree_query(now<<1|1,tree[now].mid+1,r);
    }
    
    int solve_do(int x,int y)
    {
        int pos=0;
        while(top[x]!=top[y])
        {
            if(deep[top[x]]<deep[top[y]]) swap(x,y);
            pos=pos^tree_query(1,flag[top[x]],flag[x]);
            x=f[top[x]];
        }
        if(deep[x]>deep[y]) swap(x,y);
        pos=pos^tree_query(1,flag[x],flag[y]);
        if(pos==0) return -1;
        else return pos-1;
    }
    
    int main()
    {
        in(t);
        int lit=t;
        while(t--)
        {
            memset(head,0,sizeof(head));
            in(n),in(q);cnt=0;int u,v;
            for(int i=1;i<n;i++)
            {
                in(u),in(v);
                edge_add(u,v);
                edge_add(v,u);
            }
            for(int i=1;i<=n;i++) in(dis_[i]);
            cnt=0,search_1(1,0);
            cnt=0,search_2(1,1);
            tree_build(1,1,n);
            int type;
            for(int i=1;i<=q;i++)
            {
                in(type),in(u),in(v);
                if(type) printf("%d
    ",solve_do(u,v));
                else tree_change(1,u,v+1);
            }
        }
        return 0;
    }
  • 相关阅读:
    flex属性导图
    html代码换行造成空格间距问题
    iconfont作用在css伪类中的写法
    JS模态框 简单案例
    JS实时获取输入框中的值
    JS封装addClass、removeClass
    特效 左右滑动轮播图jQuery思路
    JS 字符串两边截取空白的trim()方法的封装
    JavaScript易混淆知识点小回顾--数组方法与字符串方法;
    用GitHub来展示前端页面
  • 原文地址:https://www.cnblogs.com/IUUUUUUUskyyy/p/6415804.html
Copyright © 2020-2023  润新知