• 2017 ACM-ICPC 亚洲区(西安赛区)网络赛 G. Xor


    There is a tree with nn nodes. For each node, there is an integer value a_iai​​, (1 le a_i le 1,000,000,0001ai​​1,000,000,000 for 1 le i le n1in). There is qq queries which are described as follow: Assume the value on the path from node aa to node bb is t_0, t_1, cdots t_mt0​​,t1​​,tm​​. You are supposed to calculate t_0t0​​ xor t_ktk​​ xor t_{2k}t2k​​ xor ... xor t_{pk}tpk​​ (pk le m)(pkm).

    Input Format

    There are multi datasets. (sum n le 50,000, sum q le 500,000)(n50,000,q500,000).

    For each dataset: In the first n-1n1 lines, there are two integers u,vu,v, indicates there is an edge connect node uu and node vv.

    In the next nn lines, There is an integer a_iai​​ (1 le a_i le 1,000,000,0001ai​​1,000,000,000).

    In the next qq lines, There is three integers a,ba,band kk. (1 le a,b,k le n1a,b,kn).

    Output Format

    For each query, output an integer in one line, without any additional space.

    样例输入

    5 6
    1 5
    4 1
    2 1
    3 2
    19
    26
    0
    8
    17
    5 5 1
    1 3 2
    3 2 1
    5 4 2
    3 4 4
    1 4 5

    样例输出

    17
    19
    26
    25
    0
    19
    分析:求树上路径从距离起点为k的倍数的权值和;
       大于根号n暴力,小于的话预处理,处理到根的前缀异或和;

    代码:
    #include <iostream>
    #include <cstdio>
    #include <cstdlib>
    #include <cmath>
    #include <algorithm>
    #include <climits>
    #include <cstring>
    #include <string>
    #include <set>
    #include <bitset>
    #include <map>
    #include <queue>
    #include <stack>
    #include <vector>
    #include <cassert>
    #include <ctime>
    #define rep(i,m,n) for(i=m;i<=(int)n;i++)
    #define inf 0x3f3f3f3f
    #define mod 1000000007
    #define vi vector<int>
    #define pb push_back
    #define mp make_pair
    #define fi first
    #define se second
    #define ll long long
    #define pi acos(-1.0)
    #define pii pair<int,int>
    #define sys system("pause")
    #define ls (rt<<1)
    #define rs (rt<<1|1)
    #define all(x) x.begin(),x.end()
    const int maxn=5e4+10;
    const int N=2e5+10;
    using namespace std;
    ll gcd(ll p,ll q){return q==0?p:gcd(q,p%q);}
    ll qmul(ll p,ll q,ll mo){ll f=0;while(q){if(q&1)f=(f+p)%mo;p=(p+p)%mo;q>>=1;}return f;}
    ll qpow(ll p,ll q,ll mo){ll f=1;while(q){if(q&1)f=f*p%mo;p=p*p%mo;q>>=1;}return f;}
    int n,m,k,t,dp[maxn][310],fa[20][maxn],dep[maxn],a[maxn],sz,q,head[maxn],tot;
    struct node
    {
        int to,nxt;
    }e[maxn<<1];
    void add(int x,int y)
    {
        e[tot].to=y;
        e[tot].nxt=head[x];
        head[x]=tot++;
    }
    int lca(int x,int y)
    {
        int i;
        if(dep[x]<dep[y])swap(x,y);
        for(i=19;i>=0;i--)if(dep[fa[i][x]]>=dep[y])x=fa[i][x];
        if(x==y)return x;
        for(i=19;i>=0;i--)
        {
            if(fa[i][x]!=fa[i][y])
            {
                x=fa[i][x],
                y=fa[i][y];
            }
        }
        return fa[0][x];
    }
    int find(int x,int y)
    {
        int i;
        for(i=19;i>=0;i--)
        {
            if(y>>i&1)
            {
                x=fa[i][x];
                if(x==0)return 0;
            }
        }
        return x;
    }
    void dfs(int x,int y)
    {
        int i;
        dep[x]=dep[y]+1;
        for(i=1;fa[i-1][fa[i-1][x]];i++)
        {
            fa[i][x]=fa[i-1][fa[i-1][x]];
        }
        rep(i,1,sz)
        {
            dp[x][i]=a[x];
            dp[x][i]^=dp[find(x,i)][i];
        }
        for(i=head[x];i!=-1;i=e[i].nxt)
        {
            int z=e[i].to;
            if(z==y)continue;
            fa[0][z]=x;
            dfs(z,x);
        }
    }
    int main(){
        int i,j;
        while(~scanf("%d%d",&n,&q))
        {
            sz=round(sqrt(n));
            rep(i,1,n)
            {
                head[i]=-1;
                rep(j,0,19)fa[j][i]=0;
            }
            tot=0;
            rep(i,1,n-1)
            {
                int x,y;
                scanf("%d%d",&x,&y);
                add(x,y);add(y,x);
            }
            rep(i,1,n)scanf("%d",&a[i]);
            dfs(1,0);
            while(q--)
            {
                int x,y,k;
                int ret=0;
                scanf("%d%d%d",&x,&y,&k);
                if(x==y)
                {
                    printf("%d
    ",a[x]);
                    continue;
                }
                int fa=lca(x,y),len=dep[x]+dep[y]-2*dep[fa],pos;
                if((dep[x]-dep[fa])%k==0&&fa!=x&&fa!=y)ret^=a[fa];
                if(k>sz)
                {
                    if(fa!=x)
                    {
                        pos=x;
                        ret^=a[pos];
                        while(dep[j=find(pos,k)]>=dep[fa])
                        {
                            pos=j;
                            ret^=a[pos];
                        }
                    }
                    if(fa!=y)
                    {
                        pos=find(y,len%k);
                        if(dep[pos]>=dep[fa])
                        {
                            ret^=a[pos];
                            while(dep[j=find(pos,k)]>=dep[fa])
                            {
                                pos=j;
                                ret^=a[pos];
                            }
                        }
                    }
                }
                else
                {
                    int len1=dep[x]-dep[fa];
                    if(fa!=x)
                    {
                        len1=len1/k*k;
                        pos=find(x,len1);
                        ret=(ret^dp[x][k]^dp[pos][k]^a[pos]);
                    }
                    if(fa!=y)
                    {
                        int st=find(y,len%k);
                        if(dep[st]>=dep[fa])
                        {
                            len1=dep[st]-dep[fa];
                            len1=len1/k*k;
                            pos=find(st,len1);
                            ret=(ret^dp[st][k]^dp[pos][k]^a[pos]);
                        }
                    }
                }
                printf("%d
    ",ret);
            }
        }
        return 0;
    }
    /*
    6 1
    3 2
    1 4
    4 6
    6 2
    1 5
    60
    2
    75
    34
    60
    15
    4 6 1
    ans:45
    */
  • 相关阅读:
    【Hadoop报错】The directory item limit is exceeded: limit=1048576 items=1048576
    【Error】mysql的error.log中ranges: 268 max_threads: 4 split: 268 depth: 2是什么意思?
    【Hadoop】Hadoop集群组件默认端口
    【Python】用Python把从mysql统计的结果数据转成表格形式的图片并推送到钉钉群
    微信小程序 服务端shiro用户验证,偶然会出现验证失败的问题。
    微信小程序 数组复制 改变原数组 新数组也会自动变化
    Controller 在加入aop 后,@Autowired注入值为null
    gitblit仓库
    mybatis plus 增加数据后 返回主键id
    Shiro 访问 Swagger2报404 及 放行Swagger2
  • 原文地址:https://www.cnblogs.com/dyzll/p/7532844.html
Copyright © 2020-2023  润新知