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

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
*/
时间: 2024-10-07 17:26:34

2017 ACM-ICPC 亚洲区(西安赛区)网络赛 G. Xor的相关文章

2016 ACM/ICPC亚洲区青岛站现场赛(部分题解)

摘要 本文主要列举并求解了2016 ACM/ICPC亚洲区青岛站现场赛的部分真题,着重介绍了各个题目的解题思路,结合详细的AC代码,意在熟悉青岛赛区的出题策略,以备战2018青岛站现场赛. HDU 5984 Pocky 题意 给出一根棒子(可以吃的)的长度x和切割过程中不能小于的长度d,每次随机的选取一个位置切开,吃掉左边的一半,对右边的棒子同样操作,直至剩余的长度不大于d时停止.现在给出x和d,问切割次数的数学期望是多少. 解题思路 当看到第二个样例2 1时,结果是1.693147,联想到ln

2014ACM/ICPC亚洲区鞍山赛区现场赛——题目重现

2014ACM/ICPC亚洲区鞍山赛区现场赛--题目重现 题目链接 5小时内就搞了5题B.C.D.E,I. H题想到要打表搞了,可惜时间不够,后面打出表试了几下过了- - K题过的人也比较多,感觉是个几何旋转+ploya,但是几何实在不行没什么想法 B:这题就是一个大模拟,直接数组去模拟即可,注意细节就能过 C:类似大白上一题红蓝三角形的, 每个数字找一个互质和一个不互质个数,除掉重复就直接除2,然后总的C(n, 3)减去即可,问题在怎么处理一个数字互质和不互质的,其实只要处理出不互质的即可,这

ICPC 2018 徐州赛区网络赛

ACM-ICPC 2018 徐州赛区网络赛 ?去年博客记录过这场比赛经历:该死的水题 ?一年过去了,不被水题卡了,但难题也没多做几道.水平微微有点长进. ? ? D. Easy Math 题意: ? 给定 \(n\), \(m\) ,求 \(\sum _{i=1}^{m} \mu(in)\) .其中 $ 1 \le n \le 1e12$ , $ 1 \le m \le 2e9$ ,\(\mu(n)\) 为莫比乌斯函数. ? 思路: ? 容易知道,\(i\) 与 \(n\) 不互质时, \(\m

【分块】计蒜客17120 2017 ACM-ICPC 亚洲区(西安赛区)网络赛 G. Xor

题意:给一棵树,每个点有权值.q次询问a,b,k,问你从a点到b点,每次跳距离k,权值的异或和? 预处理每个点往其根节点的路径上隔1~sqrt(n)的距离的异或和,然后把询问拆成a->lca(a,b),lca(a,b)->b,讨论一下即可,细节比较多. 队友的代码: #include <cmath> #include <cstdio> #include <cstring> #include <iostream> #include <algo

2017 ACM/ICPC(西安)赛后总结

早上8:00的高铁,所以不得不6点前起床,向火车站赶……到达西安后已经是中午,西工大距离西安北站大概3小时车程的距离,只好先解决午饭再赶路了……下午3.30的热身赛,一行人在3.35左右赶到了赛场,坐下后立即开始读题,A题快速幂很快就通过了,B题是一道非常恶心的大模拟,本蒟蒻手敲近两小时wa的生活不能自理,终于在终场前发现一个小bug但是没有提交蛮遗憾(自信AC,捂脸逃~).晚上,回到酒店后,很早就睡觉了,并不像第一次参加区域赛那样紧张的很晚才入睡. 第二天的正式赛开始后,我和队友分别从前中后三

2016 ACM/ICPC亚洲区大连站-重现赛 解题报告

任意门:http://acm.hdu.edu.cn/showproblem.php?pid=5979 按AC顺序: I - Convex Time limit    1000 ms Memory limit 65536 kB OS Windows We have a special convex that all points have the same distance to origin point. As you know we can get N segments after linki

2014ACM/ICPC亚洲区鞍山赛区现场赛1009Osu!

鞍山的签到题,求两点之间的距离除以时间的最大值.直接暴力过的. A - Osu! Time Limit:1000MS     Memory Limit:262144KB     64bit IO Format:%I64d & %I64u Submit Status Practice HDU 5078 Appoint description:  System Crawler  (2014-10-22) Description Osu! is a very popular music game. B

西安赛区网络赛

1001.Post Robot 字符串模拟题: 1 //============================================================================ 2 // Name : 20140920.cpp 3 // Author : 4 // Version : 5 // Copyright : Your copyright notice 6 // Description : Hello World in C++, Ansi-style 7

2014ACM/ICPC亚洲区西安站现场赛 F color(二项式反演)

题意:小球排成一排,从m种颜色中选取k种颜色给n个球上色,要求相邻的球的颜色不同,求可行的方案数,答案模1e9+7.T组数据,1<= n, m <= 1e9, 1 <= k <= 1e6, k <= n, m 分析: a(k)表示用不超过k种颜色染n个位置,两两相邻颜色不相同的总数,很简单a(k)=k(n-1)^(k-1) b(k)表示恰好用k种颜色 很显然a(k)=ΣC(k,i)b(i),我们知道a,想知道b,这里就用到二项式反演 那么b(k)=ΣC(k,i)*i*(-1)