题意;n个结点的树,点带权,q次询问,问从a到b路径为t0,t1...tm,问路径上每k个点异或一次的值为多少? n<=1e4,q<=5e5.
k>sqrt(n)时 显然可以暴力往lca上跳,因为是从x->y,y往上跳时,第一次要跳dis%k.
k>sqrt(n)时 显然可以暴力往lca上跳,因为是从x->y,y往上跳时,第一次要跳dis%k.
k<sqrt(n)时 预处理出dp[u][k] u每隔k个到rt的异或值.细节看代码..
#include <bits/stdc++.h>
#define rep(i,m,n) for(i=m;i<=(int)n;i++)
#define inf 0x3f3f3f3f
const int maxn=5e4+10;
const int N=2e5+10;
using namespace std;
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;
}