记录编号 451749 评测结果 AAAAAAAAAA
题目名称 [ICPC 2017西安区域赛]树上异或xor 最终得分 100
用户昵称 GravatarFoolMike 是否通过 通过
代码语言 C++ 运行时间 1.159 s
提交时间 2017-09-18 11:26:50 内存使用 89.57 MiB
显示代码纯文本
#include<cstdio>
#include<algorithm>
using namespace std;
const int N=1e5+10;
int n,q,a[N],w[N],head[N],next[N];
void add(int f,int t){
    static int cnt=0;
    w[++cnt]=t;
    next[cnt]=head[f];
    head[f]=cnt;
}
int fa[N],dep[N],Q[N],size;
void dfs(int x){
    Q[++size]=x;
    for (int i=head[x];i;i=next[i])
    if (!fa[w[i]]) fa[w[i]]=x,dep[w[i]]=dep[x]+1,dfs(w[i]);
}
int ance[16][N];
int go(int x,int k){
    for (int i=0;i<16;i++)
        if (k>>i&1) x=ance[i][x];
    return x;
}
int lca(int x,int y){
    if (dep[x]<dep[y]) swap(x,y);
    x=go(x,dep[x]-dep[y]);
    for (int i=15;i>=0;i--)
        if (ance[i][x]!=ance[i][y]) x=ance[i][x],y=ance[i][y];
    return x!=y?fa[x]:x;
}
int up[N];
const int block_size=200;
struct array{
    int v[N];
    void init(){
        for (int i=1;i<=n;i++) up[i]=fa[up[i]];
        for (int i=1;i<=size;i++){
            int x=Q[i];
            v[x]^=a[x];
            if (up[x]) v[x]^=v[up[x]];
        }
    }
    int query(int x,int y){return v[x]^v[y]^a[y];}
}A[block_size+10];
int query(int x,int y,int k){
    if (k<=block_size) return A[k].query(x,y);
    int ans=a[y];
    for (;x!=y;x=go(x,k)) ans^=a[x];
    return ans;
}
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);
    }
    fa[1]=1;dfs(1);fa[1]=0;
    for (int i=1;i<=n;i++) scanf("%d",&a[i]),up[i]=i;
    for (int i=1;i<=block_size;i++) A[i].init();
    for (int i=1;i<=n;i++) ance[0][i]=fa[i];
    for (int j=1;j<16;j++)
    for (int i=1;i<=n;i++)
        ance[j][i]=ance[j-1][ance[j-1][i]];
    while (q--){
        int x,y,k;
        scanf("%d%d%d",&x,&y,&k);
        int LCA=lca(x,y),len=dep[x]+dep[y]-2*dep[LCA];
        int ans=query(x,go(x,(dep[x]-dep[LCA])/k*k),k);//含LCA
        int up=len%k;
        if (dep[y]-dep[LCA]>up){
            y=go(y,up);
            ans^=query(y,go(y,(dep[y]-dep[LCA]-1)/k*k),k);//不含LCA
        }
        printf("%d\n",ans);
    }
    return 0;
}