zoukankan      html  css  js  c++  java
  • HDU 5274 Dylans loves tree 树链剖分+线段树

    Dylans loves tree

    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.
     

    BC题目链接:点这里!

    题解:

      

    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    using namespace std;
    #pragma comment(linker, "/STACK:102400000,102400000")
    #define ls i<<1
    #define rs ls | 1
    #define mid ((ll+rr)>>1)
    #define pii pair<int,int>
    #define MP make_pair
    typedef long long LL;
    const long long INF = 1e18+1LL;
    const double Pi = acos(-1.0);
    const int N = 1e6+10, M = 1e3+20, mod = 1e9+7, inf = 2e9;
    
    int dep[N],head[N],t=1,sz[N],fa[N],indexS,top[N],pos[N];
    struct ss{int to,next;}e[N*2];
    int n;
    void add(int u,int v)
    {e[t].to = v;e[t].next = head[u];head[u] = t++;}
    void dfs(int u) {
        sz[u] = 1;
        dep[u] = dep[fa[u]] + 1;
        for(int i = head[u]; i; i = e[i].next) {
            int to = e[i].to;
            if(to == fa[u]) continue;
            fa[to] = u;
            dfs(to);
            sz[u] += sz[to];
        }
    }
    void dfs(int u,int chain) {
        int k = 0;
        pos[u] = ++indexS;
        top[u] = chain;
        for(int i = head[u]; i; i = e[i].next) {
            int to = e[i].to;
            if(dep[to] > dep[u] && sz[to] > sz[k])
                k = to;
        }
        if(k == 0) return ;
        dfs(k,chain);
        for(int i = head[u]; i; i = e[i].next) {
            int to = e[i].to;
            if(dep[to] > dep[u] && k != to)
                dfs(to,to);
        }
    }
    
    int sum[N],fposs[N];
    void push_up(int i,int ll,int rr) {
        sum[i] = sum[ls] ^ sum[rs];
    }
    void build(int i,int ll,int rr) {
        if(ll == rr) {
            sum[i] = fposs[ll];
            return ;
        }
        build(ls,ll,mid),build(rs,mid+1,rr);
        push_up(i,ll,rr);
    }
    void update(int i,int ll,int rr,int x,int c) {
        if(ll == rr) {
            sum[i] = c;
            return ;
        }
        if(x <= mid) update(ls,ll,mid,x,c);
        else update(rs,mid+1,rr,x,c);
        push_up(i,ll,rr);
    }
    int query(int i,int ll,int rr,int x,int y) {
        if(ll == x && rr == y) {
            return sum[i];
        }
        if(y <= mid) return query(ls,ll,mid,x,y);
        else if(x > mid) return query(rs,mid+1,rr,x,y);
        else return query(ls,ll,mid,x,mid)^query(rs,mid+1,rr,mid+1,y);
    }
    int query(int x,int y) {
        int res = 0;
        while(top[x] != top[y]) {
            if(dep[top[x]] > dep[top[y]]) {
                res ^= query(1,1,indexS,pos[top[x]],pos[x]);
                x = fa[top[x]];
            }
            else {
                res ^= query(1,1,indexS,pos[top[y]],pos[y]);
                y = fa[top[y]];
            }
        }
        if(dep[x] < dep[y])res ^= query(1,1,n,pos[x],pos[y]);
        else res ^= query(1,1,n,pos[y],pos[x]);
        return res;
    }
    int T,Q,a[N];
    void init() {
        t = 1;
        memset(fa,0,sizeof(fa));
        memset(head,0,sizeof(head));
        memset(dep,0,sizeof(dep));
        memset(sz,0,sizeof(sz));
        memset(top,0,sizeof(top));
        memset(pos,0,sizeof(pos));
        indexS = 0;
    }
    int main() {
        scanf("%d",&T);
        while(T--) {
            scanf("%d%d",&n,&Q);
            init();
            for(int i = 1; i < n; ++i) {
                int x,y;
                scanf("%d%d",&x,&y);
                add(x,y);add(y,x);
            }
            dfs(1);
            dfs(1,1);
            for(int i = 1; i <= n; ++i) scanf("%d",&a[i]);
            for(int i = 1; i <= n; ++i) fposs[pos[i]] = a[i]+1;
            build(1,1,indexS);
            while(Q--) {
                int op,x,y;
                scanf("%d%d%d",&op,&x,&y);
                if(op == 0) {
                    update(1,1,indexS,pos[x],y+1);
                } else {
                    printf("%d
    ",query(x,y)-1);
                }
            }
        }
        return 0;
    }
  • 相关阅读:
    路由基础、多app共存,路由分配、路由分发(将app自己的路由分发给应用自身管理)、反解
    Django项目的创建与介绍,三件套,静态文件,配置Mysql完成数据迁移,单表ORM记录的增删改查
    Django框架导读
    Flask简易版本、Ajax、DOM操作,表单操作
    JQuery
    0820-信心赛
    codeforces比赛总(吐)结(嘈)
    洛谷P3403 跳楼机(最短路)
    求逆序对的三种方法
    NKOJ 3751 扫雷游戏
  • 原文地址:https://www.cnblogs.com/zxhl/p/6689094.html
Copyright © 2011-2022 走看看