只有5,6过,为什么啊。
#include <iostream>
#include <cstdio>
#include <cstring>
#define int long long
using namespace std;
const int M = 120005;
const int N = 1200005;
int son[N], dep[N], siz[N], top[N], fa[N], id[N];
int n, m, r, q, cnt = 1, head[N];
int newcnt, tmp[N], w[N];
int t[N << 2], Max[N << 2];
inline int rd() {
int x = 0, w = 1;
char c = getchar();
while (c < 48 || c > 57) {
if (c == 45) w *= -1;
c = getchar();
}
while (c >= 48 && c <= 57) {
x = (x << 1) + (x << 3) + (c ^ 48);
c = getchar();
}
return x * w;
}
struct node {
int to, next, w;
} e[M];
void addi(int u, int v) {
e[++cnt].to = v;
e[cnt].next = head[u];
head[u] = cnt;
}
void add(int u, int v) {
addi(u, v);
addi(v, u);
}
void dfs1(int x, int faa, int depth) {
siz[x] = 1;
fa[x] = faa;
dep[x] = depth;
int mmax = -1;
for (int i = head[x]; i; i = e[i].next) {
int v = e[i].to;
if (v == faa) continue;
dfs1(v, x, depth + 1);
siz[x] += siz[v];
if (siz[v] > mmax) {
son[x] = v;
mmax = siz[v];
}
}
}
void dfs2(int x, int topf) {
id[x] = ++newcnt;
w[newcnt] = tmp[x];
top[x] = topf;
if (son[x]) dfs2(son[x], topf);
for (int i = head[x]; i; i = e[i].next) {
int v = e[i].to;
if (v == fa[x] || v == son[x]) continue;
dfs2(v, v);
}
}
void pushup(int rt) {
t[rt] = t[rt << 1] + t[rt << 1 | 1];
Max[rt] = max(Max[rt << 1], Max[rt << 1 | 1]);
}
inline void build(int rt, int l ,int r){
if(l == r) {
Max[rt] = t[rt] = w[l];
return;
}
int mid = (l + r) >> 1;
build(rt << 1, l, mid);
build(rt << 1 | 1, mid + 1, r);
pushup(rt);
}
inline int query(int x, int y, int l, int r, int rt) {
if(x <= l && r <= y) {
return t[rt];
}
int mid = (l + r) >> 1;
int ans = 0;
if(x <= mid) ans += query(x, y, l, mid, rt << 1);
if(y > mid) ans += query(x, y, mid + 1, r, rt << 1 | 1);
return ans ;
}
inline int max_query(int x, int y, int l, int r, int rt) {
if(x <= l && r <= y) {
return Max[rt];
}
int ans = -1e18;
int mid = (l + r) >> 1;
if(x <= mid) ans = max(ans, max_query(x, y, l, mid, rt << 1));
if(y > mid) ans = max(ans, max_query(x, y, mid + 1, r, rt << 1 | 1));
return ans;
}
inline void updateone(int x, int l, int r, int rt, int k) {
if(l == r) {
Max[rt] = t[rt] = k;
return;
}
int mid = (l + r) >> 1;
if(x <= mid) updateone(x, l, mid, rt << 1, k);
else updateone(x, mid + 1, r, rt << 1 | 1, k);
pushup(rt);
}
inline int queryrange(int x, int y) {
int ans = 0;
while (top[x] != top[y]) {
if (dep[top[x]] < dep[top[y]])swap(x, y);
ans += query(id[top[x]], id[x], 1, n ,1);
x = fa[top[x]];
}
if (dep[x] > dep[y])swap(x, y);
ans += query(id[x], id[y], 1, n, 1);
return ans;
}
inline int querymax(int x, int y) {
int ans = -1e18;
while (top[x] != top[y]) {
if (dep[top[x]] < dep[top[y]])swap(x, y);
ans = max(ans, max_query(id[top[x]], id[x], 1, n ,1));
x = fa[top[x]];
}
if (dep[x] > dep[y])swap(x, y);
ans = max(ans, max_query(id[x], id[y], 1, n, 1));
return ans;
}
signed main() {
n = rd(); r = 1;
for (int i = 1; i <= n - 1; i++) {
int u = rd(), v = rd();
add(u, v);
}
for (int i = 1; i <= n; i++) {
tmp[i] = rd();
}
dfs1(r, r, 1);
dfs2(r, r);
build(1, 1, n);
q = rd();
while(q --) {
string s;
cin >> s;
int x = rd(), y = rd();
if(s == "CHANGE"){
updateone(x, 1, n, 1, y);
}
if(s == "QMAX") {
printf("%.lld\n",querymax(x, y));
}
if(s == "QSUM") {
printf("%.lld\n",queryrange(x, y));
}
}
return 0;
}