2017 ACM-ICPC 亞洲區(西安賽區)網路賽 G. Xor
阿新 • • 發佈:2019-01-11
#include<iostream> #include<cstdio> #include<algorithm> #include<cstring> #include<cmath> using namespace std; const int maxed=50000+10; struct E { int v,bef; }e[maxed*2]; int n,m,ans,head[maxed],p[maxed]; int top[maxed],son[maxed],size_[maxed],d[maxed]; int f[maxed][20],sxor_[maxed][255]; int main() { //freopen("shuJu.txt","w",stdout); void add_(int,int); void slove_1(int,int); void slove_2(int,int); int lca(int,int); int find_(int,int); while(scanf("%d%d",&n,&m)!=EOF){ ans=1; memset(head,-1,sizeof(head)); int a,b,c; for(int i=1;i<=n-1;i++){ scanf("%d%d",&a,&b); add_(a,b); add_(b,a); } memset(f,0,sizeof(f)); for(int i=1;i<=n;i++){ scanf("%d",&p[i]); son[i]=0; if (i == 1) f[i][0] = 0; else f[i][0] = i; } d[0] = 0; memset(sxor_,0,sizeof(sxor_)); slove_1(1,1); slove_2(1,1); for(int i=1;i<=20;i++) for(int j=1;j<=n;j++){ int r=f[j][i-1]; if(r==0) continue; f[j][i]=f[r][i-1]; } int len=(int)sqrt(n); while(m--){ scanf("%d%d%d",&a,&b,&c); int wa=lca(a,b); if(c<=len){ int answer=sxor_[a][c]; int k=c-(d[a]-d[wa])%c; int kk=find_(wa,k); answer^=sxor_[kk][c]; if (d[b] - d[wa] - k >= 0 && b != wa) { kk = (d[b] - d[wa] - k)%c; int r = find_(b, kk); answer ^= sxor_[r][c]; kk = (d[a] - d[wa])%c; k = find_(wa, kk); answer ^= sxor_[k][c]; } printf("%d\n", answer); } else{ int answer = 0, l = a, r = b; while (d[l] >= d[wa]){ answer ^= p[l]; l = find_(l, c); } if (d[r] - d[wa] - (c - (d[a] - d[wa])%c) >= 0 && b != wa) { int k = (d[r] - d[wa] - (c - (d[a] - d[wa])%c))%c; r = find_(r, k); while (d[r] > d[wa]) { answer ^= p[r]; r = find_(r, c); } } printf("%d\n", answer); } } } return 0; } void add_(int x,int y) { e[ans].v=y; e[ans].bef=head[x]; head[x]=ans++; } void slove_1(int u,int dep) { size_[u]=1; d[u]=dep; int now=u,step=0; while(step<255){ sxor_[u][step]=p[u]^sxor_[now][step]; now = f[now][0]; step++; } for(int i=head[u];i!=-1;i=e[i].bef){ int v=e[i].v; if (f[u][0] == v) continue; f[v][0] = u; slove_1(v,dep+1); size_[u]+=size_[v]; if(!son[u]||size_[son[u]]<size_[v]) son[u]=v; } } void slove_2(int u,int fa) { top[u]=fa; if(son[u]) slove_2(son[u],fa); for(int i=head[u];i!=-1;i=e[i].bef){ int v=e[i].v; if (f[u][0] == v || son[u] == v) continue; slove_2(v,v); } } int lca(int a,int b) { int f1=top[a],f2=top[b],l=a,r=b; while(f1!=f2){ if(d[f1]<d[f2]){ swap(f1,f2); swap(l,r); } l = f[f1][0]; f1=top[l]; } if(d[l]>d[r]) swap(l,r); return l; } int find_(int a,int x) { int s=0; while(x){ if(x&1) a=f[a][s]; x>>=1; s++; } return a; }