http://acm.hdu.edu.cn/showproblem.php?pid=5039

给定一棵树,边权为0/1。m个操作支持翻转一条边的权值或者询问树上有多少条路径的边权和为奇数。

用树形dfs出每个点到根的路径上边权和是否为奇数;

由于翻转一个边只会连带影响其下的子节点,所有线段树记录更新区间,odd记录到根的路径上边权和为奇数的个数,每次只需更新和查询odd,没有lazy会超时

  1. #include <cstdio>
  2. #include <cstdlib>
  3. #include <cmath>
  4. #include <cstring>
  5. #include <string>
  6. #include <queue>
  7. #include <map>
  8. #include <iostream>
  9. #include <algorithm>
  10. using namespace std;
  11. #define RD(x) scanf("%d",&x)
  12. #define RD2(x,y) scanf("%d%d",&x,&y)
  13. #define RD3(x,y,z) scanf("%d%d%d",&x,&y,&z)
  14. #define clr0(x) memset(x,0,sizeof(x))
  15. typedef long long LL;
  16. #define L(x) (x<<1)
  17. #define R(x) ((x<<1)|1)
  18. #define MI(x,y) ((x+y)>>1)
  19. const int maxn = 30010;
  20. int head[maxn],l[maxn],r[maxn],val[maxn];
  21. int n,m,tot,idx;
  22. struct edge{
  23. int u,v,f,next;
  24. }ed[maxn<<1];
  25. map<string , int> hash;
  26. struct tree{
  27. int l,r,odd,// odd为到根的路径上边权和为奇数的个数
  28. lazy;// lazy控制翻转次数,翻转偶数次相当于没有翻转
  29. }d[maxn<<2];
  30. void add(int u,int v,int f)
  31. {
  32. ed[tot] = (edge){u,v,f,head[u]},head[u] = tot++;
  33. ed[tot] = (edge){v,u,f,head[v]},head[v] = tot++;
  34. }
  35. void dfs(int u,int f,int fa)
  36. {
  37. idx++;
  38. val[idx] = f;
  39. l[u] = idx;
  40. for(int i = head[u];i != -1;i = ed[i].next){
  41. if(ed[i].v != fa){
  42. dfs(ed[i].v,f ^ ed[i].f,u);
  43. }
  44. }
  45. r[u] = idx;
  46. }
  47. void up(int root)
  48. {
  49. d[root].odd = d[L(root)].odd + d[R(root)].odd;
  50. }
  51. void build(int l,int r,int root)
  52. {
  53. d[root] = (tree){l,r,val[l],0};
  54. if(l == r)
  55. return ;
  56. int mid = MI(l,r);
  57. build(l,mid,L(root));
  58. build(mid+1,r,R(root));
  59. up(root);
  60. }
  61. void down(int root) {
  62. if (d[root].lazy) {
  63. d[L(root)].lazy ^= 1;// 翻转偶数次相当于没翻转,所以不需要更新其子节点
  64. d[R(root)].lazy ^= 1;
  65. d[L(root)].odd = d[L(root)].r - d[L(root)].l + 1 - d[L(root)].odd;
  66. d[R(root)].odd = d[R(root)].r - d[R(root)].l + 1 - d[R(root)].odd;
  67. d[root].lazy = 0;
  68. }
  69. }
  70. void update(int l, int r, int root)
  71. {
  72. if (d[root].l == l && d[root].r == r) {
  73. d[root].odd = d[root].r - d[root].l + 1 - d[root].odd;
  74. d[root].lazy ^= 1;
  75. return;
  76. }
  77. down(root);
  78. int mid = MI(d[root].l,d[root].r);
  79. if (r <= mid)
  80. update(l, r, L(root));
  81. else if (l > mid)
  82. update(l, r, R(root));
  83. else {
  84. update(l, mid, L(root));
  85. update(mid + 1, r, R(root));
  86. }
  87. up(root);
  88. }
  89.  
  90. int main()
  91. {
  92. int _;
  93. RD(_);
  94. string str,rts;
  95. char q[2];
  96. for(int cas = 1;cas <= _;++cas){
  97. printf("Case #%d:\n", cas);
  98. hash.clear();
  99. RD(n);
  100. for(int i = 1;i <= n;++i){
  101. cin>>str;
  102. hash[str] = i;
  103. head[i] = -1;
  104. }
  105. tot = 0;
  106. int u,v,f;
  107. for(int i = 1;i < n;++i){
  108. cin>>str>>rts;
  109. RD(f);
  110. add(hash[str],hash[rts],f);
  111. }
  112. idx = 0;
  113. dfs(1,0,0);
  114. build(1,n,1);
  115. RD(m);
  116. while(m--){
  117. scanf("%s",q);
  118. if(q[0] == 'Q'){
  119. printf("%d\n",d[1].odd * (n - d[1].odd) * 2);
  120. }else{
  121. RD(f);
  122. f = (f-1)<<1;// 边的记录用例两单位的ed
  123. u = ed[f].u,v = ed[f].v;
  124. if(l[u] > l[v])
  125. update(l[u],r[u],1);
  126. else
  127. update(l[v],r[v],1);
  128. }
  129. }
  130. }
  131. return 0;
  132. }

hdu 5039 线段树+dfs序的更多相关文章

  1. S - Query on a tree HDU - 3804 线段树+dfs序

    S - Query on a tree HDU - 3804   离散化+权值线段树 题目大意:给你一棵树,让你求这棵树上询问的点到根节点直接最大小于等于val的长度. 这个题目和之前写的那个给你一棵 ...

  2. HDU 5692 线段树+dfs序

    Snacks Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Sub ...

  3. Tsinsen A1505. 树(张闻涛) 倍增LCA,可持久化线段树,DFS序

    题目:http://www.tsinsen.com/A1505 A1505. 树(张闻涛) 时间限制:1.0s   内存限制:512.0MB    总提交次数:196   AC次数:65   平均分: ...

  4. BZOJ_3252_攻略_线段树+dfs序

    BZOJ_3252_攻略_线段树+dfs序 Description 题目简述:树版[k取方格数] 众所周知,桂木桂马是攻略之神,开启攻略之神模式后,他可以同时攻略k部游戏.今天他得到了一款新游戏< ...

  5. 【XSY2534】【BZOJ4817】树点涂色 LCT 倍增 线段树 dfs序

    题目大意 ​ Bob有一棵\(n\)个点的有根树,其中\(1\)号点是根节点.Bob在每个点上涂了颜色,并且每个点上的颜色不同.定义一条路径的权值是:这条路径上的点(包括起点和终点)共有多少种不同的颜 ...

  6. 【bzoj4817】树点涂色 LCT+线段树+dfs序

    Description Bob有一棵n个点的有根树,其中1号点是根节点.Bob在每个点上涂了颜色,并且每个点上的颜色不同.定义一条路 径的权值是:这条路径上的点(包括起点和终点)共有多少种不同的颜色. ...

  7. R - Weak Pair HDU - 5877 离散化+权值线段树+dfs序 区间种类数

    R - Weak Pair HDU - 5877 离散化+权值线段树 这个题目的初步想法,首先用dfs序建一颗树,然后判断对于每一个节点进行遍历,判断他的子节点和他相乘是不是小于等于k, 这么暴力的算 ...

  8. 【BZOJ-3779】重组病毒 LinkCutTree + 线段树 + DFS序

    3779: 重组病毒 Time Limit: 20 Sec  Memory Limit: 512 MBSubmit: 224  Solved: 95[Submit][Status][Discuss] ...

  9. 【BZOJ-3306】树 线段树 + DFS序

    3306: 树 Time Limit: 10 Sec  Memory Limit: 256 MBSubmit: 792  Solved: 262[Submit][Status][Discuss] De ...

随机推荐

  1. JAVA动态性之一一反射机制reflection

    package com.bjsxt.reflection.test.bean; public class User { private int id; private int age; private ...

  2. Python在pycharm中编程时应该注意的问题汇总

    1.缩进问题 在 pycharm 中点击 enter 自动进行了换行缩进,此时应该注意:比如 if   else  语句,后面跟着打印输出 print 的时候,一定注意是要if语句下的输出还是else ...

  3. mysql安装笔记-rpm

    基本内容: 1.需要解决两个依赖 2.需要解决一个包冲突 3.安装mysql服务,以及客户端client 4.修改root的随机密码 5.授予root用户,从任何机器访问任何数据库的任何表的权限 1. ...

  4. 参考 - spring boot 静态变量注入值

    参考http://blog.csdn.net/zhayuyao/article/details/78553417 @Component public class A { private static ...

  5. 64位tomcat不能配32位的JDK使用

    警告: The APR based Apache Tomcat Native library failed to load. The error reported was [D:\apache-tom ...

  6. cdoj第13th校赛初赛A - AC Milan VS Juventus 【枚举】

    http://acm.uestc.edu.cn/#/contest/show/54 A - AC Milan VS Juventus Time Limit: 3000/1000MS (Java/Oth ...

  7. jquery-jsonp插件解决跨域问题

    用jquery-jsonp插件解决ajax跨域问题,既可以实现ajax同样的请求效果,而且server服务端的相关代码也不用做任何改变. 代码如下: var url="http://loca ...

  8. Cannot find autoconf. Please check your autoconf installation and the $PHP_AUTOCONF environment variable. Then, rerun this scrip

    在运行phpize时出现的错误 > /data/php/bin/phpize Configuring for: PHP Api Version: 20131106 Zend Module Api ...

  9. pycharm中的常用快捷键

    查找 Ctrl + F  替换 Ctrl + R 注释 Ctrl + /  去掉注释 Ctrl + / Function   Shortcut Use this shortcut to... Clos ...

  10. mysql添加注释

    -- 查看字段类型-- show columns from campaign_distribute --给表添加注释 -- alter table campaign_distribute commen ...