题目链接   Danil and a Part-time Job

题意    给出一系列询问或者修改操作

   $pow$ $x$表示把以$x$为根的子树的所有结点的状态取反($0$变$1$,$1$变$0$)

   $get$  $x$表示求以$x$为根的子树中状态为$1$的结点数。

首先大力$dfs$序,然后线段树操作一下。

具体问题转化为:区间翻转,区间求和。

  1. #include <bits/stdc++.h>
  2.  
  3. using namespace std;
  4.  
  5. #define rep(i, a, b) for (int i(a); i <= (b); ++i)
  6. #define dec(i, a, b) for (int i(a); i >= (b); --i)
  7. #define ls i << 1
  8. #define rs i << 1 | 1
  9. #define lson ls, L, mid
  10. #define rson rs, mid + 1, R
  11.  
  12. const int N = 2e5 + 10;
  13.  
  14. struct node{
  15. int s[2];
  16. int len;
  17. } t[N * 3];
  18.  
  19. int in[N], out[N], dc[N * 3], dt[N * 3], f[N], a[N];
  20. int n, q, ti;
  21.  
  22. vector <int> v[N];
  23.  
  24. void dfs(int x){
  25. in[x] = ++ti;
  26. f[ti] = x;
  27. for (auto u : v[x]) dfs(u);
  28. out[x] = ti;
  29. }
  30.  
  31. node update(node x, node y){
  32. node ans;
  33. ans.len = x.len + y.len;
  34. rep(i, 0, 1) ans.s[i] = x.s[i] + y.s[i];
  35. return ans;
  36. }
  37.  
  38. void build(int i, int L, int R){
  39. if (L == R){
  40. int z = a[f[L]];
  41. t[i].len = t[i].s[z] = 1;
  42. t[i].s[z ^ 1] = 0;
  43. dc[i] = -1;
  44. dt[i] = 0;
  45. return ;
  46. }
  47.  
  48. int mid = (L + R) >> 1;
  49. build(lson);
  50. build(rson);
  51. t[i] = update(t[ls], t[rs]);
  52. dc[i] = -1;
  53. dt[i] = 0;
  54. }
  55.  
  56. void cover(int i, int z){
  57. dc[i] = z;
  58. dt[i] = 0;
  59. t[i].s[z] = t[i].len;
  60. t[i].s[z ^ 1] = 0;
  61. }
  62.  
  63. void turn(int i, int z){
  64. if (~z){
  65. dc[i] ^= 1;
  66. t[i].s[z] = 0;
  67. t[i].s[z ^ 1] = t[i].len;
  68. }
  69.  
  70. else{
  71. dt[i] ^= 1;
  72. swap(t[i].s[0], t[i].s[1]);
  73. }
  74. }
  75.  
  76. void pushdown(int i){
  77. if (~dc[i]){
  78. cover(ls, dc[i]);
  79. cover(rs, dc[i]);
  80. dc[i] = -1;
  81. }
  82.  
  83. if (dt[i]){
  84. turn(ls, dc[ls]);
  85. turn(rs, dc[rs]);
  86. dt[i] = 0;
  87. }
  88. }
  89.  
  90. void Turn(int i, int L, int R, int x, int y){
  91. if (x <= L && R <= y){
  92. turn(i, dc[i]);
  93. return;
  94. }
  95.  
  96. pushdown(i);
  97. int mid = (L + R) >> 1;
  98. if (x <= mid) Turn(lson, x, y);
  99. if (y > mid) Turn(rson, x, y);
  100. t[i] = update(t[ls], t[rs]);
  101. }
  102.  
  103. int query(int i, int L, int R, int x, int y){
  104. int ret = 0;
  105. if (x <= L && R <= y) return t[i].s[1];
  106. int mid = (L + R) >> 1;
  107. pushdown(i);
  108. if (x <= mid) ret += query(lson, x, y);
  109. if (y > mid ) ret += query(rson, x, y);
  110. return ret;
  111. }
  112.  
  113. int main(){
  114.  
  115. scanf("%d", &n);
  116. rep(i, 2, n){
  117. int x;
  118. scanf("%d", &x);
  119. v[x].push_back(i);
  120. }
  121.  
  122. dfs(1);
  123. rep(i, 1, n) scanf("%d", a + i);
  124. build(1, 1, n);
  125.  
  126. for (scanf("%d", &q); q--; ){
  127. char op[10]; int x;
  128. scanf("%s%d", op, &x);
  129. if (op[0] == 'g') printf("%d\n", query(1, 1, n, in[x], out[x]));
  130. else Turn(1, 1, n, in[x], out[x]);
  131. }
  132.  
  133. return 0;
  134. }

  

Codeforces 877E Danil and a Part-time Job(dfs序 + 线段树)的更多相关文章

  1. Codeforces 877E - Danil and a Part-time Job(dfs序+线段树)

    877E - Danil and a Part-time Job 思路:dfs序+线段树 dfs序:http://blog.csdn.net/qq_24489717/article/details/5 ...

  2. Codeforces Round #225 (Div. 2) E. Propagating tree dfs序+-线段树

    题目链接:点击传送 E. Propagating tree time limit per test 2 seconds memory limit per test 256 megabytes inpu ...

  3. CodeForces 877E Danil and a Part-time Job(dfs序+线段树)

    Danil decided to earn some money, so he had found a part-time job. The interview have went well, so ...

  4. CodeForces 877E DFS序+线段树

    CodeForces 877E DFS序+线段树 题意 就是树上有n个点,然后每个点都有一盏灯,给出初始的状态,1表示亮,0表示不亮,然后有两种操作,第一种是get x,表示你需要输出x的子树和x本身 ...

  5. Codeforces Round #442 (Div. 2)A,B,C,D,E(STL,dp,贪心,bfs,dfs序+线段树)

    A. Alex and broken contest time limit per test 2 seconds memory limit per test 256 megabytes input s ...

  6. Codeforces 838B - Diverging Directions - [DFS序+线段树]

    题目链接:http://codeforces.com/problemset/problem/838/B You are given a directed weighted graph with n n ...

  7. Educational Codeforces Round 6 E dfs序+线段树

    题意:给出一颗有根树的构造和一开始每个点的颜色 有两种操作 1 : 给定点的子树群体涂色 2 : 求给定点的子树中有多少种颜色 比较容易想到dfs序+线段树去做 dfs序是很久以前看的bilibili ...

  8. Codeforces 343D Water Tree(DFS序 + 线段树)

    题目大概说给一棵树,进行以下3个操作:把某结点为根的子树中各个结点值设为1.把某结点以及其各个祖先值设为0.询问某结点的值. 对于第一个操作就是经典的DFS序+线段树了.而对于第二个操作,考虑再维护一 ...

  9. Codeforces 620E New Year Tree(DFS序 + 线段树)

    题目大概说给一棵树,树上结点都有颜色(1到60),进行下面两个操作:把某结点为根的子树染成某一颜色.询问某结点为根的子树有多少种颜色. 子树,显然DFS序,把子树结点映射到连续的区间.而注意到颜色60 ...

随机推荐

  1. python能干什么?

    python能干什么? 网络爬虫 爬虫,指的是从互联网采集数据的程序脚本 . 爬天爬地爬空气 ,无聊的时候爬一爬吃鸡数据.b站评论,能得出很多有意思的结论.知乎有个很有意思的问题——"利用爬 ...

  2. LeetCode(154) Find Minimum in Rotated Sorted Array II

    题目 Follow up for "Find Minimum in Rotated Sorted Array": What if duplicates are allowed? W ...

  3. 合肥工业大学宣城校区大学生创新创业训练项目申报书:“基于Spark平台的人工智能知识的知识图谱构建”

  4. pidgin中使用QQ

    安装     实现的功能:   可以发送静态表情 可以发送动态表情 可以发图片? 可以添加好友 可以添加群?  

  5. Linux学习-延伸正则表达式

    grep 默认仅支持基础正则表达式,如果要使用延伸型正则 表达式,你可以使用 grep -E , 不过更建议直接使用 egrep !直接区分指令比较好记忆!其 实 egrep 与 grep -E 是类 ...

  6. 使用html+javascriptt实现的简易四则运算(初学JavaScript笔记)

    今天第一天学javascript,做了个简易的四则运算,提供参考,效果图: html代码: <!DOCTYPE html> <html > <head > < ...

  7. 一个通用的分页存储过程实现-SqlServer(附上sql源码,一键执行即刻搭建运行环境)

    使用前提 查询表必须有ID字段,且该字段不能重复,建议为自增主键 背景 如果使用ADO.NET进行开发,在查询分页数据的时候一般都是使用分页存储过程来实现的,本文提供一种通用的分页存储过程,只需要传入 ...

  8. 02_ThreadLocal语法与源码分析

    文章导读: 早在JDK 1.2的版本中就提供Java.lang.ThreadLocal,ThreadLocal为解决多线程程序的并发问题提供了一种新的思路.使用这个工具类可以很简洁地编写出优美的多线程 ...

  9. Node.js中测试mysql的代码var client = mysql.createClient运行出错:TypeError: Object # has no method ‘createClient’

    今天在WebStorm下熟悉一个node.js的项目,配置环境时,手一抖,将mysql包从0.8升级到了2.1.1,结果再运行时就出错了. [Fri Mar 14 2014 17:05:49] 连接数 ...

  10. SDOJ 1195 Zhenhuan

    描述 今日又在看甄嬛传,皇上觉得后宫们的勾心斗角太险恶了,有点不好,决定给每个妃子发丝带以让后宫之间和睦相处.皇上一共有N个后宫(标号为1~n),站成一个环形(1号与n号相邻),每个后宫想要ai个丝带 ...