zoukankan      html  css  js  c++  java
  • hdu 5274 Dylans loves tree (树链剖分 + 线段树 异或)

    Dylans loves tree

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


    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.

     

    思路:
    一道非常简单的题。。要求u-v之前出现次数为奇数的数字,如果没找到就输出-1,找到就输出这个数字。
    题目保证了出现为奇数次的数字的个数不超过1,那么直接对u-v异或就好了,最后剩下的如果是0有两种可能:
    1.没有出现次数为奇数的数字 。 2.出现次数为奇数的数字为0;
    我们只要将输入的数字全部+1就可以避免这种情况了
    最后当输出的值为0时没有出现次数为奇数的数字,输出-1,不为0的话直接输出这个数字就好了。
     
    实现代码:
    #include<bits/stdc++.h>
    using namespace std;
    #define ll long long
    #define lson l,m,rt<<1
    #define rson m+1,r,rt<<1|1
    #define mid int m = (l + r) >> 1
    const int M = 2e5+10;
    struct node{
        int to,next;
    }e[M];
    int sum[M<<2],son[M],fa[M],head[M],siz[M],top[M],dep[M],tid[M],rk[M],a[M];
    int cnt1,cnt,n;
    void add(int u,int v){
        e[++cnt1].to = v;e[cnt1].next = head[u];head[u] = cnt1;
        e[++cnt1].to = u;e[cnt1].next = head[v];head[v] = cnt1;
    }
    
    void dfs1(int u,int faz,int deep){
         dep[u] = deep;
         fa[u] = faz;
         siz[u] = 1;
         for(int i = head[u];i;i=e[i].next){
            int v = e[i].to;
            if(v != fa[u]){
                dfs1(v,u,deep+1);
                siz[u] += siz[v];
                if(son[u] == -1||siz[v] > siz[son[u]])
                    son[u] = v;
            }
         }
    }
    
    void dfs2(int u,int t){
        top[u] = t;
        tid[u] = cnt;
        rk[cnt] = u;
        cnt++;
        if(son[u] == -1) return;
        dfs2(son[u],t);
        for(int i = head[u];i;i = e[i].next){
            int v = e[i].to;
            if(v != son[u]&&v != fa[u])
                dfs2(v,v);
        }
    }
    
    void pushup(int rt){
        sum[rt] = sum[rt<<1]^sum[rt<<1|1];
    }
    
    void build(int l,int r,int rt){
         if(l == r){
            sum[rt] = a[rk[l]];
            return ;
         }
         mid;
         build(lson);
         build(rson);
         pushup(rt);
    }
    
    void update(int p,int c,int l,int r,int rt){
         if(l == r){
            sum[rt] = c;
            return ;
         }
         mid;
         if(p <= m) update(p,c,lson);
         else update(p,c,rson);
         pushup(rt);
    }
    
    int query(int L,int R,int l,int r,int rt){
        if(L <= l&&R >= r){
            return sum[rt];
        }
        mid;
        int ret = 0;
        if(L <= m) ret^=query(L,R,lson);
        if(R > m) ret^=query(L,R,rson);
        return ret;
    }
    
    int ask(int x,int y){
        int sum = 0;
        int fx = top[x],fy = top[y];
        while(fx != fy){
            if(dep[fx] < dep[fy]) swap(x,y),swap(fx,fy);
            sum ^= query(tid[fx],tid[x],1,n,1);
            x = fa[fx];fx = top[x];
        }
        if(dep[x] < dep[y]) swap(x,y);
        sum^=query(tid[y],tid[x],1,n,1);
        //cout<<sum<<endl;
        return sum;
    }
    
    void init()
    {
        memset(son,-1,sizeof(son));
        for(int i = 0; i <= 2*n;i ++){
        e[i].to = 0;e[i].next = 0;head[i] = 0;
        }
    }
    int main()
    {
        int t,u,v,x,y,op,q;
        scanf("%d",&t);
        while(t--){
            scanf("%d%d",&n,&q);
            cnt = 1; cnt1 = 1;
            init();
            for(int i = 0; i < n-1;i ++){
                scanf("%d%d",&u,&v);
                add(u,v);
            }
            for(int i = 1;i <= n;i ++)
                scanf("%d",&x),a[i]=x+1;
            dfs1(1,0,1); dfs2(1,1); build(1,n,1);
            while(q--){
                scanf("%d",&op);
                if(op==1){
                    scanf("%d%d",&x,&y);
                    //cout<<ask(x,y)<<endl;
                    if(ask(x,y)!=0) printf("%d
    ",ask(x,y)-1);
                    else printf("-1
    ");
                }
                else{
                    scanf("%d%d",&x,&y);
                    update(tid[x],y+1,1,n,1);
                }
            }
        }
        return 0;
    }
  • 相关阅读:
    python自学笔记
    mybatis审查要点
    session和cookie的简单理解
    linux命令
    [个人原创]关于java中对象排序的一些探讨(三)
    [技术翻译]Guava官方文档Ordering
    [个人原创]关于java中对象排序的一些探讨(二)
    [个人原创]关于java中对象排序的一些探讨(一)
    from 2666
    Euler Project question 34 in python way
  • 原文地址:https://www.cnblogs.com/kls123/p/8964291.html
Copyright © 2011-2022 走看看