将树通过树链剖分转化成线性序列,用线段树维护最值,和值即可。

  1 #include <bits/stdc++.h>
2 using namespace std;
3 const int N = 3e4 + 10;
4 int n, m, head[N], to[N << 1], nxt[N << 1], tot;
5 int total, fa[N], dep[N], size[N], son[N], top[N];
6 int w[N], id[N], rev[N];
7 int Max, Sum;
8 struct node{
9 int mx, sum;
10 }t[N << 2];
11 void add(int x, int y) {
12 nxt[++ tot] = head[x]; head[x] = tot; to[tot] = y;
13 }
14 void dfs1(int u, int f) { //求dep,fa,size,son
15 size[u] = 1;
16 for (int i = head[u]; i; i = nxt[i]) {
17 int v = to[i];
18 if (v == f) continue;
19 dep[v] = dep[u] + 1;
20 fa[v] = u;
21 dfs1(v, u);
22 size[u] += size[v];
23 if (size[v] > size[son[u]]) son[u] = v;
24 }
25 }
26 void dfs2(int u, int t) { //求top,id,rev
27 top[u] = t;
28 id[u] = ++ total; // u对应的dfs序下标
29 rev[total] = u; // dfs序下标对应的u
30 if (!son[u]) return ;
31 dfs2(son[u], t);//先沿重儿子dfs
32 for (int i = head[u]; i; i = nxt[i]) {
33 int v = to[i];
34 if (v != fa[u] && v != son[u]) dfs2(v, v);
35 }
36 }
37 namespace SegmentTree {
38 #define mid ((l + r) >> 1)
39 #define lson k << 1, l, mid
40 #define rson k << 1 | 1, mid + 1, r
41 void pushup(int k) {
42 t[k].mx = max(t[k << 1].mx, t[k << 1 | 1].mx);
43 t[k].sum = t[k << 1].sum + t[k << 1 | 1].sum;
44 }
45 void build(int k, int l, int r) {
46 if (l == r) {
47 t[k].mx = t[k].sum = w[rev[l]];
48 return ;
49 }
50 build(lson), build(rson);
51 pushup(k);
52 }
53 void update(int k, int l, int r, int pos, int v) {
54 if (l == r) {
55 t[k].mx = t[k].sum = v;
56 return ;
57 }
58 if (pos <= mid) update(lson, pos, v);
59 else update(rson, pos, v);
60 pushup(k);
61 }
62 void query(int k, int l, int r, int L, int R) {
63 if (L <= l && R >= r) {
64 Max = max(Max, t[k].mx);
65 Sum += t[k].sum;
66 return ;
67 }
68 if (L <= mid) query(lson, L, R);
69 if (R > mid) query(rson, L, R);
70 }
71 void ask(int u, int v) {
72 while (top[u] != top[v]) {
73 if(dep[top[u]] < dep[top[v]]) swap(u, v);
74 query(1, 1, total, id[top[u]], id[u]);
75 u = fa[top[u]];
76 }
77 if (dep[u] > dep[v]) swap(u, v);
78 query(1, 1, total, id[u], id[v]);
79 }
80 }
81 using namespace SegmentTree;
82 int main() {
83 int x, y; char str[10];
84 scanf("%d", &n);
85 for (int i = 1; i < n; i ++) {
86 scanf("%d %d", &x, &y);
87 add(x, y), add(y, x);
88 }
89 for (int i = 1; i <= n; i ++) scanf("%d", &w[i]);
90 dep[1] = 1;
91 dfs1(1, 0);
92 dfs2(1, 1);
93 build(1, 1, total);
94 scanf("%d", &m);
95 for (int i = 1; i <= m; i ++) {
96 scanf("%s", str);
97 scanf("%d %d", &x, &y);
98 if(str[0] == 'C') update(1, 1, total, id[x], y);
99 else {
100 Sum = 0;
101 Max = -0x3f3f3f3f;
102 ask(x, y);
103 if (str[1] == 'M') printf("%d\n", Max);
104 else printf("%d\n", Sum);
105 }
106 }
107 return 0;
108 }

最新文章

  1. WebService 生成类的命令语句
  2. 阿里云安装Tomcat
  3. MyEclipse10中自动生成Hibernate的实体和xml配置文件
  4. LintCode Binary Tree Preorder Traversal
  5. CentOS 6.3 安装 phpmyadmin
  6. UVA127- &quot;Accordian&quot; Patience(模拟链表)
  7. ural 1126 Magnetic Storms
  8. [置顶] Linux协议栈代码阅读笔记(一)
  9. 伪元素first-letter(首字母变大)
  10. IIS7如何显示详细错误信息
  11. kali切换字符界面模式和切换图形界面模式
  12. Kail Linux的安装方法
  13. 树莓派的系统安装,并且利用网线直连 Mac 进行配置
  14. .NET Core实战项目之CMS 第十章 设计篇-系统开发框架设计
  15. 转:Excel—“撤销工作表保护密码”的破解并获取原始密码
  16. 【漫画】程序员永远修不好的Bug——情人节
  17. Jmeter压力测试生成聚合报告
  18. linux 播放加密DVDs
  19. 【ARM】2440裸机系列-gpio按键控制
  20. python 正则表达式的使用

热门文章

  1. Thread类的常用方法_sleep和创建多线程程序的第二种方式实现Runnable接口
  2. C++ 实现可变参数的三个方法
  3. while,do while,for循环语句
  4. Latex查表
  5. CMAKE编译时如何自动下载第三方库并解压、安装到指定目录
  6. Luogu1064 金明的预算方案 (有依赖的背包)
  7. 神器 利器 Typora
  8. Excel 工作簿、工作表与单元格
  9. pre 预格式化文本标签
  10. ifort + mkl + impi (全套intel)编译安装量子化学软件GAMESS 2022 R1版本