感谢QAQ
#include <bits/stdc++.h>
using namespace std;
#define ll long long
struct edge
{
int u, v, w;
} ee[200010];
int n, m;
int hd[200010], ed[400010], nt[400010], cnt;
int fa[200010], dep[200010], sz[200010], son[200010];
int top[200010], dfn[200010], rnk[200010], tim;
struct SegTree
{
#define lc (i << 1)
#define rc ((i << 1) | 1)
#define mid ((l + r) >> 1)
struct Tree
{
int sum, mx, mn;
int tag = 1;
} s[800010];
void push_up (int i)
{
s[i].sum = s[lc].sum + s[rc].sum;
s[i].mx = max (s[lc].mx, s[rc].mx);
s[i].mn = min (s[lc].mn, s[rc].mn);
}
void push_down (int i)
{
int tg = s[i].tag;
s[i].tag = 1;
s[lc].sum = tg * s[lc].sum;
s[rc].sum = tg * s[rc].sum;
s[lc].tag = tg * s[lc].tag;
s[rc].tag = tg * s[rc].tag;
if (tg == -1)
{
int k = s[lc].mx;
s[lc].mx = -s[lc].mn;
s[lc].mn = -k;
k = s[rc].mx;
s[rc].mx = -s[rc].mn;
s[rc].mn = -k;
}
}
void changeC (int i, int l, int r, int x, int d)
{
if (l == r && l == x)
{
s[i].sum = s[i].mx = s[i].mn = d;
return;
}
if (r < x || x < l)
return;
push_down (i);
changeC (lc, l, mid, x, d);
changeC (rc, mid + 1, r, x, d);
push_up (i);
}
void changeN (int i, int l, int r, int L, int R)
{
if (L <= l && r <= R)
{
s[i].tag = -s[i].tag;
s[i].sum = -s[i].sum;
if (s[i].tag == -1)
{
int k = s[i].mx;
s[i].mx = -s[i].mn;
s[i].mn = -k;
}
return;
}
if (r < L || R < l)
return;
push_down (i);
changeN (lc, l, mid, L, R);
changeN (rc, mid + 1, r, L, R);
push_up (i);
}
int queryS (int i, int l, int r, int L, int R)
{
if (L <= l && r <= R)
{
return s[i].sum;
}
if (r < L || R < l)
return 0;
push_down (i);
return queryS (lc, l, mid, L, R) + queryS (rc, mid + 1, r, L, R);
}
int queryX (int i, int l, int r, int L, int R)
{
if (L <= l && r <= R)
{
return s[i].mx;
}
if (r < L || R < l)
return -1001;
push_down (i);
return max (queryX (lc, l, mid, L, R), queryX (rc, mid + 1, r, L, R));
}
int queryN (int i, int l, int r, int L, int R)
{
if (L <= l && r <= R)
{
return s[i].mn;
}
if (r < L || R < l)
return 1001;
push_down (i);
return min (queryN (lc, l, mid, L, R), queryN (rc, mid + 1, r, L, R));
}
} ST;
void add_edge (int u, int v)
{
ed[++cnt] = v;
nt[cnt] = hd[u];
hd[u] = cnt;
}
void dfs1 (int u, int ft)
{
fa[u] = ft;
dep[u] = dep[ft] + 1;
sz[u] = 1;
for (int i = hd[u]; i; i = nt[i])
{
int v = ed[i];
if (v == ft)
continue;
dfs1 (v, u);
sz[u] += sz[v];
if (sz[son[u]] < sz[v])
son[u] = v;
}
}
void dfs2 (int u, int tp)
{
top[u] = tp;
dfn[u] = ++tim;
rnk[tim] = u;
if (!son[u])
return;
dfs2 (son[u], tp);
for (int i = hd[u]; i; i = nt[i])
{
int v = ed[i];
if (v == fa[u] || v == son[u])
continue;
dfs2 (v, v);
}
}
void changeN (int u, int v)
{
while (top[u] != top[v])
{
if (dep[top[u]] < dep[top[v]])
swap (u, v);
ST.changeN (1, 1, n, dfn[top[u]], dfn[u]);
u = fa[top[u]];
}
if (dep[u] < dep[v])
swap (u, v);
ST.changeN (1, 1, n, dfn[v] + 1, dfn[u]);
}
int queryS (int u, int v)
{
int sum = 0;
while (top[u] != top[v])
{
if (dep[top[u]] < dep[top[v]])
swap (u, v);
sum += ST.queryS (1, 1, n, dfn[top[u]], dfn[u]);
u = fa[top[u]];
}
if (dep[u] < dep[v])
swap (u, v);
sum += ST.queryS (1, 1, n, dfn[v] + 1, dfn[u]);
return sum;
}
int queryX (int u, int v)
{
int mx = -1001;
while (top[u] != top[v])
{
if (dep[top[u]] < dep[top[v]])
swap (u, v);
mx = max (mx, ST.queryX (1, 1, n, dfn[top[u]], dfn[u]));
u = fa[top[u]];
}
if (dep[u] < dep[v])
swap (u, v);
mx = max (mx, ST.queryX (1, 1, n, dfn[v] + 1, dfn[u]));
return mx;
}
int queryN (int u, int v)
{
int mn = 1001;
while (top[u] != top[v])
{
if (dep[top[u]] < dep[top[v]])
swap (u, v);
mn = min (mn, ST.queryN (1, 1, n, dfn[top[u]], dfn[u]));
u = fa[top[u]];
}
if (dep[u] < dep[v])
swap (u, v);
mn = min (mn, ST.queryN (1, 1, n, dfn[v] + 1, dfn[u]));
return mn;
}
int main()
{
cin >> n;
for (int i = 1; i < n; i++)
{
int u, v, w;
cin >> u >> v >> w;
u++;
v++;
add_edge (u, v);
add_edge (v, u);
ee[i] = {u, v, w};
}
dfs1 (1, 0);
dfs2 (1, 1);
for (int i = 1; i < n; i++)
{
auto &k = ee[i];
if (dep[k.u] > dep[k.v])
swap (k.u, k.v);
ST.changeC (1, 1, n, dfn[k.v], k.w);
}
cin >> m;
for (int i = 1; i <= m; i++)
{
string op;
int u, v;
cin >> op >> u >> v;
u++;
v++;
if (op == "C")
ST.changeC (1, 1, n, ee[u - 1].v, v - 1);
else if (op == "N")
changeN (u, v);
else if (op == "SUM")
cout << queryS (u, v) << endl;
else if (op == "MAX")
cout << queryX (u, v) << endl;
else
cout << queryN (u, v) << endl;
}
return 0;
}