记录编号 593837 评测结果 AAAAAAAAAA
题目名称 [ICPC 2017西安区域赛]树上异或xor 最终得分 100
用户昵称 Gravatar小金 是否通过 通过
代码语言 C++ 运行时间 0.912 s
提交时间 2024-09-17 16:50:53 内存使用 16.77 MiB
显示代码纯文本
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath> 
using namespace std;
int q,a[50010],fa[50010][20],s[50010][250],nxt[100010],to[100010],head[100010],tot,sq,n,vis[50010],deep[50010];
void add(int u,int v)
{
    tot++;
    nxt[tot]=head[u];
    head[u]=tot;
    to[tot]=v;
}
int get(int now,int x)
{
    for(int i=17;i>=0;--i)
    {
        if(x>=(1<<i))
        {
           now=fa[now][i];
           x-=(1<<i);
        }
    }
    return now;
}
void dfs(int now)
{
    vis[now]=1;
    for(int i=1;i<=17;++i)
    {
        fa[now][i]=fa[fa[now][i-1]][i-1];
    }
    for(int i=1;i<=sq;++i)
    {
        s[now][i]=s[get(now,i)][i]^a[now];
    }
    for(int i=head[now];i;i=nxt[i])
    {
        if(!vis[to[i]])
        {
           fa[to[i]][0]=now;
           deep[to[i]]=deep[now]+1;
           dfs(to[i]);
        }
    }
}
int lca(int u,int v)
{
    for(int i=17;i>=0;--i)
    {
        if(deep[fa[u][i]]>=deep[v]) u=fa[u][i];
    }
    for(int i=17;i>=0;--i)
    {
        if(deep[fa[v][i]]>=deep[u])
        v=fa[v][i];
    }
    if(u==v) return u;
    for(int i=17;i>=0;--i)
    {
        if(fa[u][i]!=fa[v][i])
        {
           u=fa[u][i];
           v=fa[v][i];
        }
    }
    return fa[u][0];
}
int main()
{
    freopen("xor_xian.in","r",stdin);
    freopen("xor_xian.out","w",stdout);
    scanf("%d%d",&n,&q);
    for(int i=1;i<n;++i)
    {
        int u,v;
        scanf("%d%d",&u,&v);
        add(u,v);
        add(v,u);
    }
    sq=sqrt(n);
    for(int i=1;i<=n;++i)
    {
        scanf("%d",&a[i]);
    } 
    deep[1]=1;
    dfs(1);
    for(int i=1;i<=q;++i)
    {
        int u,v,k;
        scanf("%d%d%d",&u,&v,&k);
        if(k<=sq)
        {
            int nowans=0;
            int l=lca(u,v);
            int l1=(deep[u]-deep[l])%k;
            int ll=get(l,k-l1);
            nowans^=s[u][k];
            nowans^=s[ll][k];
            int l2=(deep[v]-deep[l]);
            if(l2>=k-l1&&v!=l)
            {
                l2-=(k-l1);
                v=get(v,l2%k);
                l1=(deep[v]-deep[l])%k;
                if(l1==0) ll=l;
                else ll=get(l,k-l1);
                nowans^=s[v][k];
                nowans^=s[ll][k];
            }
            printf("%d\n",nowans);
        }
        else
        {
                 
            int nowans=0;
            int l=lca(u,v);
            int l1=(deep[u]-deep[l])%k;
            int ll=get(l,k-l1);
            int now=u;
            while(deep[now]>=deep[l])
            {
                nowans^=a[now];
                now=get(now,k);
            }
            int l2=(deep[v]-deep[l]);
            if(l2>=k-l1&&v!=l)
            {
                l2-=(k-l1);
                v=get(v,l2%k);
                now=v;
                while(deep[now]>deep[l])
                {
                    nowans^=a[now];
                    now=get(now,k);
                }
            }
            printf("%d\n",nowans);
        }
    }
    tot=0;
    for(int i=1;i<=n;++i)
    {
        head[i]=0;
        for(int j=1;j<=sq;++j)
        {
            s[i][j]=0;
        }   
        a[i]=0;
        vis[i]=0;
        deep[i]=0;
        for(int j=0;j<=17;++j)
        {
            fa[i][j]=0;
        } 
    }
    return 0;
}