Rt.
#include <bits/stdc++.h>
#define ll long long
using namespace std;
ll N, M, value[200005];
struct Edge {
ll nxt, to, w;
} edge[400005];
ll cnt, head[200005];
void add(ll u, ll v, ll w)
{
++ cnt;
edge[cnt].nxt = head[u];
edge[cnt].to = v;
edge[cnt].w = w;
head[u] = cnt;
}
ll sz[200005], heavyson[200005], father[200005], depth[200005];
void dfs1(ll u, ll fa, ll dep)
{
sz[u] = 1;
father[u] = fa;
depth[u] = dep;
for(ll i = head[u]; i; i = edge[i].nxt)
{
ll v = edge[i].to;
if(v == fa) continue;
dfs1(v, u, dep + 1);
value[v] = edge[i].w;
sz[u] += sz[v];
if(sz[v] > sz[heavyson[u]]) heavyson[u] = v;
}
}
ll dfncnt, dfn[200005], linktop[200005], newvalue[200005];
ll edgetodfn[200005];
void dfs2(ll u, ll lktp)
{
dfn[u] = ++ dfncnt;
linktop[u] = lktp;
newvalue[dfn[u]] = value[u];
if(!heavyson[u]) return;
dfs2(heavyson[u], lktp);
for(ll i = head[u]; i; i = edge[i].nxt)
{
ll v = edge[i].to;
if(v == father[u] || v == heavyson[u]) continue;
dfs2(v, v);
}
}
#define lson ((p << 1) | 0)
#define rson ((p << 1) | 1)
#define mid ((l + r) >> 1)
struct SegmentTree {
ll sum, max, min, lazytag_inv;
} T[(200005 << 2) + 5];
void merge(ll p)
{
T[p].sum = T[lson].sum + T[rson].sum;
T[p].max = max(T[lson].max, T[rson].max);
T[p].min = min(T[lson].min, T[rson].min);
}
void pushdown(ll l, ll r, ll p)
{
ll lmax = T[lson].max, lmin = T[lson].min, rmax = T[rson].max, rmin = T[rson].min;
T[lson].sum = -T[lson].sum, T[rson].sum = -T[rson].sum, T[lson].max = -lmin, T[lson].min = -lmax, T[rson].max = -rmin, T[rson].min = -rmax, T[lson].lazytag_inv = !T[lson].lazytag_inv, T[rson].lazytag_inv = !T[rson].lazytag_inv;
T[p].lazytag_inv = 0;
}
void build(ll l, ll r, ll p)
{
if(l == r)
{
T[p].sum = T[p].max = T[p].min = newvalue[l];
return;
}
build(l, mid, lson); build(mid + 1, r, rson);
merge(p);
}
void modify_let(ll l, ll r, ll x, ll p, ll val)
{
if(l == r)
{
T[p].sum = T[p].max = T[p].min = val;
return;
}
if(T[p].lazytag_inv) pushdown(l, r, p);
if(x <= mid) modify_let(l, mid, x, lson, val);
if(x >= mid + 1) modify_let(mid + 1, r, x, rson, val);
merge(p);
}
void modify_inv(ll l, ll r, ll lll, ll rrr, ll p)
{
if(lll <= l && rrr >= r)
{
ll pmax = T[p].max, pmin = T[p].min;
T[p].lazytag_inv = !T[p].lazytag_inv, T[p].sum = -T[p].sum, T[p].max = -pmin, T[p].min = -pmax;
return;
}
if(T[p].lazytag_inv) pushdown(l, r, p);
if(lll <= mid) modify_let(l, mid, lll, rrr, lson);
if(rrr >= mid + 1) modify_let(mid + 1, r, lll, rrr, rson);
merge(p);
}
void modify_inv_simplepath(ll x, ll y)
{
while(linktop[x] != linktop[y])
{
if(depth[linktop[x]] < depth[linktop[y]]) swap(x, y);
modify_inv(1, N, dfn[linktop[x]], dfn[x], 1);
x = father[linktop[x]];
}
if(depth[x] > depth[y]) swap(x, y);
if(x != y) modify_inv(1, N, dfn[x] + 1, dfn[y], 1);
}
ll query_sum(ll l, ll r, ll lll, ll rrr, ll p)
{
if(lll <= l && rrr >= r)
return T[p].sum;
ll res = 0;
if(T[p].lazytag_inv) pushdown(l, r, p);
if(lll <= mid) res += query_sum(l, mid, lll, rrr, lson);
if(rrr >= mid + 1) res += query_sum(mid + 1, r, lll, rrr, rson);
return res;
}
ll query_max(ll l, ll r, ll lll, ll rrr, ll p)
{
if(lll <= l && rrr >= r)
return T[p].max;
ll res = LLONG_MIN;
if(T[p].lazytag_inv) pushdown(l, r, p);
if(lll <= mid) res = max(res, query_max(l, mid, lll, rrr, lson));
if(rrr >= mid + 1) res = max(res, query_max(mid + 1, r, lll, rrr, rson));
return res;
}
ll query_min(ll l, ll r, ll lll, ll rrr, ll p)
{
if(lll <= l && rrr >= r)
return T[p].min;
ll res = LLONG_MAX;
if(T[p].lazytag_inv) pushdown(l, r, p);
if(lll <= mid) res = min(res, query_min(l, mid, lll, rrr, lson));
if(rrr >= mid + 1) res = min(res, query_min(mid + 1, r, lll, rrr, rson));
return res;
}
ll query_sum_simplepath(ll x, ll y)
{
ll res = 0;
while(linktop[x] != linktop[y])
{
if(depth[linktop[x]] < depth[linktop[y]]) swap(x, y);
res += query_sum(1, N, dfn[linktop[x]], dfn[x], 1);
x = father[linktop[x]];
}
if(depth[x] > depth[y]) swap(x, y);
if(x != y) res += query_sum(1, N, dfn[x] + 1, dfn[y], 1);
return res;
}
ll query_max_simplepath(ll x, ll y)
{
ll res = LLONG_MIN;
while(linktop[x] != linktop[y])
{
if(depth[linktop[x]] < depth[linktop[y]]) swap(x, y);
res = max(res, query_max(1, N, dfn[linktop[x]], dfn[x], 1));
x = father[linktop[x]];
}
if(depth[x] > depth[y]) swap(x, y);
if(x != y) res = max(res, query_max(1, N, dfn[x] + 1, dfn[y], 1));
return res;
}
ll query_min_simplepath(ll x, ll y)
{
ll res = LLONG_MAX;
while(linktop[x] != linktop[y])
{
if(depth[linktop[x]] < depth[linktop[y]]) swap(x, y);
res = min(res, query_min(1, N, dfn[linktop[x]], dfn[x], 1));
x = father[linktop[x]];
}
if(depth[x] > depth[y]) swap(x, y);
if(x != y) res = min(res, query_min(1, N, dfn[x] + 1, dfn[y] , 1));
return res;
}
pair<ll, ll> tmpedge[200005];
signed main()
{
cin >> N;
for(ll i = 1; i < N; ++ i)
{
ll a, b, c;
cin >> a >> b >> c;
++ a, ++ b;
add(a, b, c); add(b, a, c);
tmpedge[i] = make_pair(a, b);
}
dfs1(1, 1, 1);
dfs2(1, 1);
build(1, N, 1);
cin >> M;
for(ll i = 1; i <= M; ++ i)
{
string opr;
cin >> opr;
if(opr == "C")
{
ll E, W, tmp = 0;
cin >> E >> W;
if(depth[tmpedge[E].first] > depth[tmpedge[E].second]) tmp = tmpedge[E].first;
else tmp = tmpedge[E].second;
modify_let(1, N, dfn[tmp], 1, W);
}
if(opr == "N")
{
ll U, V;
cin >> U >> V;
++ U, ++ V;
modify_inv_simplepath(U, V);
}
if(opr == "SUM")
{
ll U, V;
cin >> U >> V;
++ U, ++ V;
cout << query_sum_simplepath(U, V) << endl;
}
if(opr == "MAX")
{
ll U, V;
cin >> U >> V;
++ U, ++ V;
cout << query_max_simplepath(U, V) << endl;
}
if(opr == "MIN")
{
ll U, V;
cin >> U >> V;
++ U, ++ V;
cout << query_min_simplepath(U, V) << endl;
}
}
return 0;
}