首页 > 其他 > 详细

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

时间:2017-09-16 21:13:43      阅读:526      评论:0      收藏:0      [点我收藏+]

There is a tree with nn nodes. For each node, there is an integer value a_ia?i??, (1 \le a_i \le 1,000,000,0001≤a?i??≤1,000,000,000 for 1 \le i \le n1≤i≤n). 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_mt?0??,t?1??,?t?m??. You are supposed to calculate t_0t?0?? xor t_kt?k?? xor t_{2k}t?2k?? xor ... xor t_{pk}t?pk?? (pk \le m)(pk≤m).

Input Format

There are multi datasets. (\sum n \le 50,000, \sum q \le 500,000)(∑n≤50,000,∑q≤500,000).

For each dataset: In the first n-1n−1 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_ia?i?? (1 \le a_i \le 1,000,000,0001≤a?i??≤1,000,000,000).

In the next qq lines, There is three integers a,ba,band kk. (1 \le a,b,k \le n1≤a,b,k≤n).

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\n",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\n",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
*/

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

原文:http://www.cnblogs.com/dyzll/p/7532844.html

踩
(0)
赞
(0)
   
举报
评论 一句话评论(0)
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!