题意:给一棵树,每个点有权值。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 <algorithm>
using namespace std;
int q,a[50004],fa[50004][18],s[50004][230],nxt[100005],to[100005],head[100005],en,sq,n,vis[50004],deep[50004];
void add(int u,int v)
{
nxt[++en]=head[u];
head[u]=en;
to[en]=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()
{
while(scanf("%d%d",&n,&q)!=EOF)
{
int u,v,k;
for(int i=1;i<n;++i)
{
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)
{
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);
}
}
en=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;
}

最新文章

  1. css之浮动
  2. GIT远程仓库地址变更
  3. Expected BEGIN_OBJECT but was BEGIN_ARRAY at line 1 column 2 path 解决办法
  4. SNAT,是源地址转换,其作用是将ip数据包的源地址转换成另外一个地址
  5. 06---Net基础加强
  6. IOS 实现自定义的导航栏背景以及自定义颜色的状态栏(支持7.0以及低版本)
  7. oc 基础知识
  8. 玩玩Hibernate(二)hibernate-spider爬虫~~
  9. Android中ListView分页加载数据
  10. css控制图片变灰色,彩色
  11. 不同浏览器对URL最大长度的限制
  12. 关于JS中获取浏览器高度和宽度值的多种方法(多浏览器)
  13. “selection does not contain a main type”解决方法
  14. 利用python处理文档中各字段出现的次数并排序
  15. 学习总结javascript和ajax,php,和css
  16. 程序员周末阿里面试,5分钟就被一道题秒杀:HashMap与Hashtable
  17. Javascript中的词法作用域、动态作用域、函数作用域和块作用域(四)
  18. 20135234mqy-——信息安全系统设计基础第十二周学习总结
  19. LINUX下IDEA等工具调试项目时提示:Unable to open debugger port
  20. jpa summary

热门文章

  1. Katu Puzzle(POJ3678+2-SAT问题+tarjan缩点)
  2. 抓其根本(一)(hdu2710 Max Factor 素数 最大公约数 最小公倍数.....)
  3. c语言中的size_t
  4. peewee外键性能问题
  5. 448D - Codeforces
  6. 一个文档让vim飞起来
  7. python实战===国内很简单实用的一些开源的api以及开源项目
  8. ubuntu命令行操作mysql常用操作
  9. JPA注解一对多报Could not determine type for: java.util.List错误
  10. ReentrantLock 分析