【题目链接】 http://acm.hdu.edu.cn/showproblem.php?pid=5274

【题目大意】

  给出一棵树,每个点有一个权值,权值可修改,且大于等于0,询问链上出现次数为奇数的数,题目保证每次询问的链上最多只有一个数出现次数为奇数。如果不存在这样的数,就输出-1。

【题解】

  题目等价于求链上点的异或和,树链剖分,线段树维护区间异或和,然后链上查询即可,注意到存在权值为0的特殊情况,所以我们将更新的数字都+1,在最后处理答案的时候-1即可。

【代码】

  1. #include <cstdio>
  2. #include <algorithm>
  3. #include <climits>
  4. #include <cstring>
  5. using namespace std;
  6. const int N=300010;
  7. int val[N],tot,op,x,d[N],num[N],ed=0,u,w,n,m,i,v[N],vis[N],f[N],g[N],nxt[N],size[N],son[N],st[N],en[N],dfn,top[N],t;char ch;
  8. void add(int x,int y){v[++ed]=y;nxt[ed]=g[x];g[x]=ed;}
  9. void dfs(int x){
  10. size[x]=1;
  11. for(int i=g[x];i;i=nxt[i])if(v[i]!=f[x]){
  12. f[v[i]]=x,d[v[i]]=d[x]+1;
  13. dfs(v[i]),size[x]+=size[v[i]];
  14. if(size[v[i]]>size[son[x]])son[x]=v[i];
  15. }
  16. }
  17. void dfs2(int x,int y){
  18. if(x==-1)return;
  19. st[x]=++dfn;top[x]=y;
  20. if(son[x])dfs2(son[x],y);
  21. for(int i=g[x];i;i=nxt[i])if(v[i]!=son[x]&&v[i]!=f[x])dfs2(v[i],v[i]);
  22. en[x]=dfn;
  23. }
  24. struct Node{int l,r;int sum;}T[N*4];
  25. void build(int x,int l,int r){
  26. T[x].l=l;T[x].r=r;T[x].sum=0;
  27. if(l==r)return;int mid=(l+r)>>1;
  28. build(x<<1,l,mid);build((x<<1)|1,mid+1,r);
  29. }
  30. void up(int x){T[x].sum=T[x<<1].sum^T[x<<1|1].sum;}
  31. void update(int x,int k,int val){
  32. if(T[x].l==k&&T[x].r==k){T[x].sum^=val;return;}
  33. int mid=(T[x].l+T[x].r)>>1;
  34. if(k<=mid)update(x<<1,k,val);
  35. else update((x<<1)|1,k,val); up(x);
  36. }
  37. int sum(int x,int l,int r){
  38. if(l<=T[x].l&&T[x].r<=r)return T[x].sum;
  39. int mid=(T[x].l+T[x].r)>>1,tmp=0;
  40. if(l<=mid)tmp^=sum(x<<1,l,r);
  41. if(r>mid)tmp^=sum((x<<1)|1,l,r);
  42. return tmp;
  43. }
  44. int chain(int x,int y){
  45. int res=0;
  46. for(;top[x]!=top[y];x=f[top[x]]){
  47. if(d[top[x]]<d[top[y]]){int z=x;x=y;y=z;}
  48. res^=sum(1,st[top[x]],st[x]);
  49. }if(d[x]<d[y]){int z=x;x=y;y=z;}
  50. res^=sum(1,st[y],st[x]);
  51. return res;
  52. }
  53. void init(){
  54. memset(g,dfn=ed=tot=0,sizeof(g));
  55. memset(v,0,sizeof(v));
  56. memset(nxt,0,sizeof(nxt));
  57. memset(son,-1,sizeof(son));
  58. }
  59. int cas;
  60. int main(){
  61. scanf("%d",&cas);
  62. while(cas--){
  63. init();
  64. scanf("%d%d",&n,&m);
  65. for(int i=1;i<n;i++){
  66. scanf("%d%d",&u,&w);
  67. add(u,w); add(w,u);
  68. }dfs(1);dfs2(1,1);
  69. build(1,1,dfn);
  70. for(int i=1;i<=n;i++){
  71. scanf("%d",&val[i]); val[i]++;
  72. update(1,st[i],val[i]);
  73. }
  74. while(m--){
  75. scanf("%d%d%d",&op,&u,&w);
  76. if(op){
  77. printf("%d\n",chain(u,w)-1);
  78. }else{
  79. update(1,st[u],val[u]^(w+1));
  80. val[u]=w+1;
  81. }
  82. }
  83. }return 0;
  84. }

  

HDU 5274 Dylans loves tree(树链剖分)的更多相关文章

  1. Hdu 5274 Dylans loves tree (树链剖分模板)

    Hdu 5274 Dylans loves tree (树链剖分模板) 题目传送门 #include <queue> #include <cmath> #include < ...

  2. hdu 5274 Dylans loves tree (树链剖分 + 线段树 异或)

    Dylans loves tree Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Othe ...

  3. HDU 5274 Dylans loves tree 树链剖分+线段树

    Dylans loves tree Problem Description Dylans is given a tree with N nodes. All nodes have a value A[ ...

  4. hdu 5274 Dylans loves tree(LCA + 线段树)

    Dylans loves tree Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Othe ...

  5. HDU 5274 Dylans loves tree(LCA+dfs时间戳+成段更新 OR 树链剖分+单点更新)

    Problem Description Dylans is given a tree with N nodes. All nodes have a value A[i].Nodes on tree i ...

  6. hdu 5274 Dylans loves tree

    Dylans loves tree http://acm.hdu.edu.cn/showproblem.php?pid=5274 Time Limit: 2000/1000 MS (Java/Othe ...

  7. POJ3237 Tree 树链剖分 边权

    POJ3237 Tree 树链剖分 边权 传送门:http://poj.org/problem?id=3237 题意: n个点的,n-1条边 修改单边边权 将a->b的边权取反 查询a-> ...

  8. HDU 5614 Baby Ming and Matrix tree 树链剖分

    题意: 给出一棵树,每个顶点上有个\(2 \times 2\)的矩阵,矩阵有两种操作: 顺时针旋转90°,花费是2 将一种矩阵替换为另一种矩阵,花费是10 树上有一种操作,将一条路经上的所有矩阵都变为 ...

  9. HDU 5044 Tree --树链剖分

    题意:给一棵树,两种操作: ADD1: 给u-v路径上所有点加上值k, ADD2:给u-v路径上所有边加上k,初始值都为0,问最后每个点和每条边的值,输出. 解法:树链剖分可做,剖出来如果直接用线段树 ...

随机推荐

  1. 创建、更新、删除文档。 --- Mongodb权威指南阅读。

    插入文档: db.foo.insert({ "key" : "value"}); 使用insert插入一个数据,文档中如果没有_id 会自动给文档增加_id. ...

  2. 生成php所需要的APNS Service pem证书的步骤

    1.登录到 iPhone Developer Connection Portal 并点击 App IDs 2.创建一个不使用通配符的 App ID .通配符 ID 不能用于推送通知服务.例如,我们的i ...

  3. HTML豆ちしき

    HTML文档里所有的空白符(空格,Tab,换行,回车)会被浏览器忽略,唯一的例外是空格,对空格的处理方式是所有连续的空格被当成一个空格,不管有一个,还是两个,还是100个.之所以有这样的规则是因为忽略 ...

  4. php获取网页内容方法 小偷程序 采集程序

    抓取到的内容在通过正则表达式做一下过滤就得到了你想要的内容,至于如何用正则表达式过滤,在这里就不做介绍了,有兴趣的,以下就是几种常用的用php抓取网页中的内容的方法.1.file_get_conten ...

  5. MySQL二进制日志中保存的上下文信息

    1.二进制日志中要保存上下文的原因 二进制日志是要在slave端重放的,记录上下文信息,是为了保证主丛数据库的一致.如rand一个随机数,在主上返回的可以有是100,在从上返回的可能就是1000了. ...

  6. SQL Server MYSQL 检查点的好处

    执行检查点时: 如果一个事务不没有提交.日志缓存还是会被更新到磁盘上的物理文件. 这样做就使得大事务commit 时也特别快!

  7. 在cad中画一条长500mm,垂直90度的线段

    视频教程奉上 方法1.点击线段按钮,鼠标指定一点,输入500,再输入<90. 方法2,点击线段按钮,鼠标指定一点,输入500,按tab,再输入90.

  8. Android手机app启动的时候第一个Activity必须是MainActivity吗

    原文:Android手机app启动的时候第一个Activity必须是MainActivity吗 Android手机APP启动的第一个Activity是可以自己设置的,不是必须的MainActivity ...

  9. Unix/Linux环境C编程入门教程(8) FreeBSD CCPP开发环境搭建

    1. FreeBSD是一种自由类Unix操作系统,是由经过BSD.386BSD和4.4BSD发展而来的类Unix的一个重要分支.FreeBSD拥有超过200名活跃开发者和上千名贡献者.FreeBSD被 ...

  10. Java程序员快速入门Go语言

    这篇文章帮助Java程序员快速入门Go语言. 转载至 开源中国社区. http://www.oschina.net 本文将以一个有代表性的例子为开始,以此让Java程序员对Go语言有个初步认识,随后将 ...