题目描述:

给定一颗树,求某个节点的子树的val值之和

可以用树的前序遍历给每一个节点编号,从而可以确定一个节点的子树的范围,这样就可以进行直接在区间上进行统计了。

vector < int > Map[maxN]写成typedef vector <int> INT; vector <INT> Map(maxN);就不超时了。

线段树

  1. #include <cstdio>
  2. #include <cstring>
  3. #include <cstdlib>
  4. #include <cstring>
  5. #include <iostream>
  6. #include <algorithm>
  7. #include <cmath>
  8. #include <vector>
  9. #define LL long long
  10. using namespace std;
  11. //线段树
  12. //区间每点增值,求区间和
  13. const int maxN = ;
  14. struct node
  15. {
  16. int lt, rt;
  17. int val;
  18. }tree[*maxN];
  19.  
  20. //向上更新
  21. void pushUp(int id)
  22. {
  23. tree[id].val = tree[id<<].val + tree[id<<|].val;
  24. }
  25.  
  26. //建立线段树
  27. void build(int lt, int rt, int id)
  28. {
  29. tree[id].lt = lt;
  30. tree[id].rt = rt;
  31. // tree[id].val = 1;//每段的初值,根据题目要求
  32. if (lt == rt)
  33. {
  34. tree[id].val=;
  35. return;
  36. }
  37. int mid = (lt+rt)>>;
  38. build(lt, mid, id<<);
  39. build(mid+, rt, id<<|);
  40. pushUp(id);
  41. }
  42.  
  43. //增加区间内每个点固定的值
  44. void add(int lt, int rt, int id)
  45. {
  46. if (lt <= tree[id].lt && rt >= tree[id].rt)
  47. {
  48. if(tree[id].val==)
  49. tree[id].val=;
  50. else
  51. tree[id].val=;
  52. return;
  53. }
  54. int mid = (tree[id].lt+tree[id].rt)>>;
  55. if (lt <= mid)
  56. add(lt, rt, id<<);
  57. if (rt > mid)
  58. add(lt, rt, id<<|);
  59. pushUp(id);
  60. }
  61.  
  62. //查询某段区间内的和
  63. int query(int lt, int rt, int id)
  64. {
  65. if (lt <= tree[id].lt && rt >= tree[id].rt)
  66. return tree[id].val;
  67. int mid = (tree[id].lt+tree[id].rt)>>;
  68. int ans = ;
  69. if (lt <= mid)
  70. ans += query(lt, rt, id<<);
  71. if (rt > mid)
  72. ans += query(lt, rt, id<<|);
  73. return ans;
  74. }
  75.  
  76. struct NODE
  77. {
  78. int cnt,l,r;
  79. }a[maxN];
  80. typedef vector<int > INT;
  81. vector<INT > Map(maxN);
  82. int vis[maxN];
  83. int number;
  84. void dfs(int fa)
  85. {
  86. for(int i=;i<Map[fa].size();i++)
  87. {
  88. int son=Map[fa][i];
  89. if(vis[son]==)
  90. {
  91. a[son].cnt=++number;
  92. a[son].l= number;
  93. vis[son]=;
  94. dfs(son);
  95. a[son].r=number;
  96. }
  97. }
  98. }
  99. void init()
  100. {
  101. for(int i=;i<maxN;i++)
  102. Map[i].clear();
  103. }
  104. int main()
  105. {
  106. // freopen("test.txt","r",stdin);
  107. int n,m;
  108. while(~scanf("%d",&n))
  109. {
  110. init();
  111. for(int i=;i<=n-;i++)
  112. {
  113. int from,to;
  114. scanf("%d%d",&from,&to);
  115. Map[from].push_back(to);
  116. Map[to].push_back(from);
  117. }
  118. number=;
  119. memset(vis,,sizeof(vis));
  120. a[].cnt=;
  121. a[].l=;
  122. vis[]=;
  123.  
  124. dfs();
  125.  
  126. a[].r=number;
  127.  
  128. build(a[].l,a[].r,);
  129. //for(int i=1;i<=9;i++)
  130. // printf("%d %d %d\n",a[i].cnt,a[i].l,a[i].r);
  131. int M;
  132. scanf("%d",&M);
  133. char str[]; int id;
  134. while(M--)
  135. {
  136. scanf("%s%d",str,&id);
  137. //printf("%s\n",str);
  138. if(str[]=='Q')
  139. {
  140. printf("%d\n",query(a[id].l,a[id].r,) );
  141. }
  142. if(str[]=='C')
  143. {
  144. add(a[id].cnt,a[id].cnt,);
  145. }
  146. }
  147. }
  148. return ;
  149. }

树状数组

  1. #include <cstdio>
  2. #include <cstring>
  3. #include <cstdlib>
  4. #include <cstring>
  5. #include <iostream>
  6. #include <algorithm>
  7. #include <cmath>
  8. #include <vector>
  9. #define LL long long
  10. using namespace std;
  11. const int maxN = ;
  12. int n;
  13. //树状数组
  14. int C[maxN],A[maxN];
  15. int lowbit(int x)
  16. {
  17. return x&(-x);
  18. }
  19. int sum(int x)
  20. {
  21. int ret=;
  22. while(x>)
  23. {
  24. ret+=C[x]; x-=lowbit(x);
  25. }
  26. return ret;
  27. }
  28. void update(int x,int pls)
  29. {
  30. int d;
  31. if(pls==)
  32. {
  33. if(A[x]==)
  34. d=;
  35. if(A[x]==)
  36. d=-;
  37. }
  38. else
  39. d=;
  40. A[x]+=d;
  41. while(x<=n)
  42. {
  43. C[x]+=d; x+=lowbit(x);
  44. }
  45. }
  46. struct NODE
  47. {
  48. int cnt,l,r;
  49. }a[maxN];
  50. typedef vector<int> INT;
  51. vector < INT > Map(maxN);
  52. int vis[maxN];
  53. int number;
  54. void dfs(int fa)
  55. {
  56. for(int i=;i<Map[fa].size();i++)
  57. {
  58. int son=Map[fa][i];
  59. if(vis[son]==)
  60. {
  61. a[son].cnt=++number;
  62. a[son].l= number;
  63. vis[son]=;
  64. dfs(son);
  65. a[son].r=number;
  66. }
  67. }
  68. }
  69. void init()
  70. {
  71. for(int i=;i<maxN;i++)
  72. Map[i].clear();
  73. }
  74. int main()
  75. {
  76. //freopen("test.txt","r",stdin);
  77. while(~scanf("%d",&n))
  78. {
  79. init();
  80. for(int i=;i<=n-;i++)
  81. {
  82. int from,to;
  83. scanf("%d%d",&from,&to);
  84. Map[from].push_back(to);
  85. Map[to].push_back(from);
  86. }
  87. number=;
  88. memset(vis,,sizeof(vis));
  89. a[].cnt=;
  90. a[].l=;
  91. vis[]=;
  92.  
  93. dfs();
  94.  
  95. a[].r=number;
  96. memset(C,,sizeof(C));
  97. memset(A,,sizeof(A));
  98. for(int i=;i<=n;i++)
  99. update(i,);
  100. int M;
  101. scanf("%d",&M);
  102. char str[]; int id;
  103. while(M--)
  104. {
  105. scanf("%s%d",str,&id);
  106. if(str[]=='Q')
  107. {
  108. printf("%d\n",sum(a[id].r) -sum(a[id].l-) );
  109. }
  110. if(str[]=='C')
  111. {
  112. update(a[id].cnt,);
  113. }
  114. }
  115. }
  116. return ;
  117. }

poj 3321(带时间戳 + 区间统计)的更多相关文章

  1. poj 3321 单点更新 区间求和

    Apple Tree Time Limit: 2000 MS Memory Limit: 65536 KB 64-bit integer IO format: %I64d , %I64u Java c ...

  2. POJ.3321 Apple Tree ( DFS序 线段树 单点更新 区间求和)

    POJ.3321 Apple Tree ( DFS序 线段树 单点更新 区间求和) 题意分析 卡卡屋前有一株苹果树,每年秋天,树上长了许多苹果.卡卡很喜欢苹果.树上有N个节点,卡卡给他们编号1到N,根 ...

  3. Hdu 3887 Counting Offspring \ Poj 3321 Apple Tree \BZOJ 1103 [POI2007]大都市meg

    这几个题练习DFS序的一些应用. 问题引入: 给定一颗n(n <= 10^5)个节点的有根树,每个节点标有权值,现有如下两种操作: 1.C x y     以节点x的权值修改为y. 2.Q x ...

  4. hdu 1540 Tunnel Warfare(线段树区间统计)

    Tunnel Warfare Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) T ...

  5. POJ 3321:Apple Tree + HDU 3887:Counting Offspring(DFS序+树状数组)

    http://poj.org/problem?id=3321 http://acm.hdu.edu.cn/showproblem.php?pid=3887 POJ 3321: 题意:给出一棵根节点为1 ...

  6. poj 3321 Apple Trie

    /* poj 3321 Apple Trie 这道题的关键是如何将一个树建成一个一维数组利用树状数组来解题! 可以利用dfs()来搞定,我们在对一个节点深搜后,所经过的节点的数目就是该节点的子树的数目 ...

  7. POJ 3321 Apple Tree(DFS序+线段树单点修改区间查询)

    Apple Tree Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 25904   Accepted: 7682 Descr ...

  8. bzoj 3065: 带插入区间K小值 替罪羊树 && AC300

    3065: 带插入区间K小值 Time Limit: 60 Sec  Memory Limit: 512 MBSubmit: 1062  Solved: 253[Submit][Status] Des ...

  9. 洛谷P2879 [USACO07JAN]区间统计Tallest Cow

    To 洛谷.2879 区间统计 题目描述 FJ's N (1 ≤ N ≤ 10,000) cows conveniently indexed 1..N are standing in a line. ...

随机推荐

  1. [HAOI2006]受欢迎的牛(tarjan缩点)

    洛谷传送门 直接tarjan求scc,然后统计出度为0的缩点,如果多余1个就输出0,只有一个就输出这个缩点里的点. ——代码 #include <cstdio> #include < ...

  2. POJ2479【DP 枚举】

    题意:给出一串数字,求出其中不重不交的两个子串的和的最大值 思路:最近最大子串和做多了,感觉这题有点水.枚举分割点,将序列分成左右两串,然后看左右串的最大子串和的最大值. //poj2479 #inc ...

  3. 【dfs】codeforces Journey

    http://codeforces.com/contest/839/problem/C [AC] #include<iostream> #include<cstdio> #in ...

  4. CCF 201712-4 90分

    90分,不知道错在哪里了,dijkstra算法,用一个数组的d[i]表示以i点结尾的小路的长度,以i点为中心扩展时,若下一点为k,如果i->k是小路,则 d[j] = d[k]+M[k][j]; ...

  5. HTTP错误:java.lang.IllegalArgumentException: Illegal character in scheme at index 0: http://xxxxxx

    读取T卡文件里的域名,HTTP请求出现如下错误 java.lang.IllegalArgumentException: Illegal character in scheme at index 0: ...

  6. ***apache做301重定向的方法

    将不带www的定向到带www去 方法一:加在httpd.conf 1.这里我使用mod_rewrite重写URL的方式来做,做之前朋友记得检查一下你的apache是否已经加载了rewrite模块.如图 ...

  7. 洛谷—— P1186 玛丽卡

    https://www.luogu.org/problem/show?pid=1186 题目描述 麦克找了个新女朋友,玛丽卡对他非常恼火并伺机报复. 因为她和他们不住在同一个城市,因此她开始准备她的长 ...

  8. The Bottom of a Graph

                                    poj——The Bottom of a Graph Time Limit: 3000MS   Memory Limit: 65536K ...

  9. [Bzoj4817] [Sdoi2017]树点涂色 (LCT神题)

    4817: [Sdoi2017]树点涂色 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 629  Solved: 371[Submit][Status ...

  10. 学习日常笔记<day14>自定义标签

    1自定义标签 1.1第一个自定义标签开发步骤 1)编写一个普通的java类,继承SimpleTagSupport类,叫标签处理器类 /** * 标签处理器类 * @author APPle * 1)继 ...