题意:

给出一棵树,每个顶点上有一个权值。

操作:选择一条路径,并将路径上所有的点的权值同时加或减某个数。

查询:某个点的当前权值

分析:

树链剖分完毕后,就是简单的线段树区间更新。

提交的时候注意要要加一句扩栈的代码,用C++提交。

  1. #include <cstdio>
  2. #include <cstring>
  3. #include <algorithm>
  4. using namespace std;
  5.  
  6. void read(int& x) {
  7. x = ;
  8. char c = ' ';
  9. while(c < '' || c > '') c = getchar();
  10. while('' <= c && c <= '') {
  11. x = x * + c - '';
  12. c = getchar();
  13. }
  14. }
  15.  
  16. const int maxn = + ;
  17. const int maxnode = maxn * ;
  18.  
  19. struct Edge
  20. {
  21. int v, nxt;
  22. Edge() {}
  23. Edge(int v, int nxt) :v(v), nxt(nxt) {}
  24. };
  25.  
  26. int n, m, q;
  27. int a[maxn];
  28.  
  29. int ecnt, head[maxn];
  30. Edge edges[maxn * ];
  31.  
  32. void AddEdge(int u, int v) {
  33. edges[++ecnt] = Edge(v, head[u]);
  34. head[u] = ecnt;
  35. edges[++ecnt] = Edge(u, head[v]);
  36. head[v] = ecnt;
  37. }
  38.  
  39. int dep[maxn], fa[maxn], son[maxn], sz[maxn];
  40.  
  41. int tot, id[maxn], pos[maxn], top[maxn];
  42.  
  43. void dfs(int u) {
  44. sz[u] = ; son[u] = -;
  45. for(int i = head[u]; i; i = edges[i].nxt) {
  46. int v = edges[i].v;
  47. if(v == fa[u]) continue;
  48. fa[v] = u;
  49. dep[v] = dep[u] + ;
  50. dfs(v);
  51. sz[u] += sz[v];
  52. if(son[u] == - || sz[v] > sz[son[u]]) son[u] = v;
  53. }
  54. }
  55.  
  56. void dfs2(int u, int tp) {
  57. top[u] = tp;
  58. id[u] = ++tot;
  59. pos[tot] = u;
  60. if(son[u] == -) return;
  61. if(son[u]) dfs2(son[u], tp);
  62. for(int i = head[u]; i; i = edges[i].nxt) {
  63. int v = edges[i].v;
  64. if(v == fa[u] || v == son[u]) continue;
  65. dfs2(v, v);
  66. }
  67. }
  68.  
  69. int sumv[maxnode], addv[maxnode];
  70. char cmd[];
  71.  
  72. void pushup(int o) { sumv[o] = sumv[o<<] + sumv[o<<|]; }
  73.  
  74. void build(int o, int L, int R) {
  75. if(L == R) { sumv[o] = a[pos[L]]; return; }
  76. int M = (L + R) / ;
  77. build(o<<, L, M);
  78. build(o<<|, M+, R);
  79. pushup(o);
  80. }
  81.  
  82. void pushdown(int o, int L, int R) {
  83. if(addv[o]) {
  84. addv[o<<] += addv[o];
  85. addv[o<<|] += addv[o];
  86. int M = (L + R) / ;
  87. sumv[o<<] += (M - L + ) * addv[o];
  88. sumv[o<<|] += (R - M) * addv[o];
  89. addv[o] = ;
  90. }
  91. }
  92.  
  93. void update(int o, int L, int R, int qL, int qR, int v) {
  94. if(qL <= L && R <= qR) {
  95. sumv[o] += (R - L + ) * v;
  96. addv[o] += v;
  97. return;
  98. }
  99. pushdown(o, L, R);
  100. int M = (L + R) / ;
  101. if(qL <= M) update(o<<, L, M, qL, qR, v);
  102. if(qR > M) update(o<<|, M+, R, qL, qR, v);
  103. pushup(o);
  104. }
  105.  
  106. void UPDATE(int u, int v, int val) {
  107. int t1 = top[u], t2 = top[v];
  108. while(t1 != t2) {
  109. if(dep[t1] < dep[t2]) { swap(u, v); swap(t1, t2); }
  110. update(, , n, id[t1], id[u], val);
  111. u = fa[t1]; t1 = top[u];
  112. }
  113. if(dep[u] > dep[v]) swap(u, v);
  114. update(, , n, id[u], id[v], val);
  115. }
  116.  
  117. int query(int o, int L, int R, int p) {
  118. if(L == R) return sumv[o];
  119. pushdown(o, L, R);
  120. int M = (L + R) / ;
  121. if(p <= M) return query(o<<, L, M, p);
  122. else return query(o<<|, M+, R, p);
  123. }
  124.  
  125. int main()
  126. {
  127. while(scanf("%d%d%d", &n, &m, &q) == ) {
  128. for(int i = ; i <= n; i++) read(a[i]);
  129.  
  130. memset(head, , sizeof(head));
  131. ecnt = ;
  132. for(int i = ; i < n; i++) {
  133. int u, v; read(u); read(v);
  134. AddEdge(u, v);
  135. }
  136.  
  137. dfs();
  138. tot = ;
  139. dfs2(, );
  140.  
  141. memset(addv, , sizeof(addv));
  142. build(, , n);
  143.  
  144. while(q--) {
  145. scanf("%s", cmd);
  146. int u, v, d;
  147. read(u);
  148. if(cmd[] == 'Q') {
  149. printf("%d\n", query(, , n, id[u]));
  150. } else {
  151. read(v); read(d);
  152. if(cmd[] == 'D') d = -d;
  153. UPDATE(u, v, d);
  154. }
  155. }
  156. }
  157.  
  158. return ;
  159. }

代码君

HDU 3966 RE 树链剖分 线段树 Aragorn's Story的更多相关文章

  1. HDU 2460 Network(双连通+树链剖分+线段树)

    HDU 2460 Network 题目链接 题意:给定一个无向图,问每次增加一条边,问个图中还剩多少桥 思路:先双连通缩点,然后形成一棵树,每次增加一条边,相当于询问这两点路径上有多少条边,这个用树链 ...

  2. Aragorn's Story 树链剖分+线段树 && 树链剖分+树状数组

    Aragorn's Story 来源:http://www.fjutacm.com/Problem.jsp?pid=2710来源:http://acm.hdu.edu.cn/showproblem.p ...

  3. 【BZOJ-2325】道馆之战 树链剖分 + 线段树

    2325: [ZJOI2011]道馆之战 Time Limit: 40 Sec  Memory Limit: 256 MBSubmit: 1153  Solved: 421[Submit][Statu ...

  4. 【BZOJ2243】[SDOI2011]染色 树链剖分+线段树

    [BZOJ2243][SDOI2011]染色 Description 给定一棵有n个节点的无根树和m个操作,操作有2类: 1.将节点a到节点b路径上所有点都染成颜色c: 2.询问节点a到节点b路径上的 ...

  5. BZOJ2243 (树链剖分+线段树)

    Problem 染色(BZOJ2243) 题目大意 给定一颗树,每个节点上有一种颜色. 要求支持两种操作: 操作1:将a->b上所有点染成一种颜色. 操作2:询问a->b上的颜色段数量. ...

  6. POJ3237 (树链剖分+线段树)

    Problem Tree (POJ3237) 题目大意 给定一颗树,有边权. 要求支持三种操作: 操作一:更改某条边的权值. 操作二:将某条路径上的边权取反. 操作三:询问某条路径上的最大权值. 解题 ...

  7. bzoj4034 (树链剖分+线段树)

    Problem T2 (bzoj4034 HAOI2015) 题目大意 给定一颗树,1为根节点,要求支持三种操作. 操作 1 :把某个节点 x 的点权增加 a . 操作 2 :把某个节点 x 为根的子 ...

  8. HDU4897 (树链剖分+线段树)

    Problem Little Devil I (HDU4897) 题目大意 给定一棵树,每条边的颜色为黑或白,起始时均为白. 支持3种操作: 操作1:将a->b的路径中的所有边的颜色翻转. 操作 ...

  9. Aizu 2450 Do use segment tree 树链剖分+线段树

    Do use segment tree Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://www.bnuoj.com/v3/problem_show ...

  10. 【POJ3237】Tree(树链剖分+线段树)

    Description You are given a tree with N nodes. The tree’s nodes are numbered 1 through N and its edg ...

随机推荐

  1. 【持续更新】Java 时间相关

    直接上代码: import java.util.*; import java.text.SimpleDateFormat; public class HelloWorld { public stati ...

  2. 关于rabbitmq的消息路由的同步问题

    http://www.cnblogs.com/me-sa/archive/2012/11/12/rabbitmq_ram_or_disk_node.html我是看了上面的博客明白了一些原理的,我之前一 ...

  3. Kendo 单页面应用(一)概述

    Kendo 单页面应用(一)概述 Kendo 单页面应用(Single-Page Application,缩写为 SPA)定义了一组类用于简化 Web 应用(Rich Client)开发,最常见的单页 ...

  4. zblog去除底部版权信息 “请勿修改或删除主题版权及作者信息”

    场景:使用了免费模板,但底部带作者版权.删除版权信息的代码后访问前台弹窗:请勿修改或删除主题版权及作者信息... 1. 删除版权信息代码 使用notepad++搜索功能,搜索版权信息:如ABC,找到相 ...

  5. SQLSERVER是怎麽通过索引和统计信息来找到目标数据的(第三篇)

    SQLSERVER是怎麽通过索引和统计信息来找到目标数据的(第三篇) 最近真的没有什么精力写文章,天天加班,为了完成这个系列,硬着头皮上了 再看这篇文章之前请大家先看我之前写的第一篇和第二篇 第一篇: ...

  6. 洛谷 P2324 [SCOI2005]骑士精神

    题目描述 输入输出格式 输入格式: 第一行有一个正整数T(T<=10),表示一共有N组数据.接下来有T个5×5的矩阵,0表示白色骑士,1表示黑色骑士,*表示空位.两组数据之间没有空行. 输出格式 ...

  7. 使用JPA + Eclipselink操作PostgreSQL数据库

    首先确保您已经安装了PostgreSQL.您可以参考我这篇文章PostgreSQL扫盲教程. 使用Eclipse创建一个新的JPA project: Platform选择EclipseLink,作为J ...

  8. UVA 1599, POJ 3092 Ideal Path 理想路径 (逆向BFS跑层次图)

    大体思路是从终点反向做一次BFS得到一个层次图,然后从起点开始依次向更小的层跑,跑的时候选则字典序最小的,由于可能有多个满足条件的点,所以要把这层满足条件的点保存起来,在跑下一层.跑完一层就会得到这层 ...

  9. Memcached笔记之分布式算法

    1.根据余数进行分散:离散度高,但是增加或者移除服务器的时候,缓存充足的代价非常大.添加服务器后,余数就会产生巨变,这样就无法获取与保存时相同的服务器,从而音像缓存的命中率. 2.Consistent ...

  10. java ArrayList remove 2 及正确方法

    https://www.cnblogs.com/chrischennx/p/9610853.html 正确方式 方法一,还是fori,位置前挪了减回去就行了, remove后i--: public v ...