#include <bits/stdc++.h>
#define int long long
using namespace std;
int n;
template<typename T>
T read(T x)
{
T opt = 1, sum = 0;
char ch = getchar();
while(!isdigit(ch)) opt = (ch == '-') ? -1 : 1, ch = getchar();
while( isdigit(ch)) sum = (sum << 1) + (sum << 3) + (ch ^ 48), ch = getchar();
return opt * sum;
}
#define read read(0ll)
const int N = 1e5 + 5;
int w[N], dep[N], fa[N], sz[N], temp[N], son[N], top[N], _, id[N], a[N];
pair<int, int> yexo[N];
vector<int> g[N];
void dfs1(int u, int f, int deep)
{
dep[u] = deep;
fa[u] = f;
sz[u] = 1;
int maxn = -1;
for(int i = 0;i < g[u].size();i ++ ){
int v = g[u][i];
if(v == f) continue;
dfs1(v, u, deep + 1);
temp[v] = w[u];
sz[u] += sz[v];
if(sz[v] > maxn)
{
maxn = sz[v];
son[u] = v;
}
}
}
void dfs2(int u, int topf)
{
top[u] = topf;
id[u] = ++_;
a[_] = temp[u];
if(!son[u]) return ;
dfs2(son[u], topf);
for(int i = 0;i < g[u].size();i ++ ){
int v = g[u][i];
if(v == fa[u] || v == son[u]) continue;
dfs2(v, v);
}
}
struct Segment
{
struct node
{
int l, r, sum, maxn, minn, lazy;
}tr[N << 2];
void push_up(int u)
{
tr[u].sum = tr[u << 1].sum + tr[u << 1 | 1].sum;
tr[u].maxn = max(tr[u << 1].maxn, tr[u << 1 | 1].maxn);
tr[u].minn = min(tr[u << 1].minn, tr[u << 1 | 1].minn);
}
void pushdown(int u)
{
tr[u << 1].lazy ^= 1, tr[u << 1 | 1].lazy ^= 1;
tr[u << 1].maxn = -tr[u << 1].maxn, tr[u << 1 | 1].maxn = -tr[u << 1 | 1].maxn;
tr[u << 1].minn = -tr[u << 1].minn, tr[u << 1 | 1].minn = -tr[u << 1 | 1].minn;
tr[u << 1].sum = -tr[u << 1].sum, tr[u << 1 | 1].sum = -tr[u << 1 | 1].sum;
swap(tr[u << 1].maxn, tr[u << 1].minn);
swap(tr[u << 1 | 1].maxn, tr[u << 1 | 1].minn);
tr[u].lazy = 0;
}
void build(int u, int l, int r)
{
tr[u].l = l, tr[u].r = r;
tr[u].lazy = 0;tr[u].maxn = INT_MIN, tr[u].minn = INT_MAX;
if(l == r) {
tr[u].sum = tr[u].maxn = tr[u].minn = a[l]; return ;
}
int mid = (l + r) / 2;
build(u << 1, l, mid), build(u << 1 | 1, mid + 1, r);
push_up(u);
}
void reupdate(int u, int l, int r, int ll, int rr)
{
if(ll <= l && r <= rr)
{
tr[u].lazy ^= 1;
tr[u].maxn = -tr[u].maxn, tr[u].minn = -tr[u].minn, swap(tr[u].maxn, tr[u].minn);
tr[u].sum = -tr[u].sum;
return ;
}
if(tr[u].lazy) pushdown(u);
int mid = (l + r) / 2;
if(ll <= mid) reupdate(u << 1, l, mid, ll, rr);
if(rr > mid) reupdate(u << 1, mid + 1, r, ll, rr);
push_up(u);
}
void update(int u, int l, int r, int q, int val)
{
if(l == r)
{
tr[u].maxn = tr[u].minn = tr[u].sum = val;
return ;
}
if(tr[u].lazy) pushdown(u);
int mid = (l + r) / 2;
if(q <= mid) update(u << 1, l, mid, q, val);
if(q > mid) update(u << 1, mid + 1, r, q, val);
push_up(u);
}
int querysum(int u, int l, int r, int ll, int rr)
{
if(ll <= l && r <= rr)
{
return tr[u].sum;
}
if(tr[u].lazy) pushdown(u);
int mid = (l + r) / 2;
int res = 0;
if(ll <= mid) res += querysum(u << 1, l, mid, ll, rr);
if(rr > mid) res += querysum(u << 1, mid + 1, r, ll, rr);
push_up(u);
return res;
}
int querymaxn(int u, int l, int r, int ll, int rr)
{
if(ll <= l && r <= rr)
{
return tr[u].maxn;
}
if(tr[u].lazy) pushdown(u);
int mid = (l + r) / 2;
int res = INT_MIN;
if(ll <= mid) res = max(res, querymaxn(u << 1, l, mid, ll, rr));
if(rr > mid) res = max(res, querymaxn(u << 1, mid + 1, r, ll, rr));
push_up(u);
return res;
}
int queryminn(int u, int l, int r, int ll, int rr)
{
if(ll <= l && r <= rr)
{
return tr[u].minn;
}
if(tr[u].lazy) pushdown(u);
int mid = (l + r) / 2;
int res = INT_MAX;
if(ll <= mid) res = min(res, queryminn(u << 1, l, mid, ll, rr));
if(rr > mid) res = min(res, queryminn(u << 1, mid + 1, r, ll, rr));
push_up(u);
return res;
}
}seg;
struct Tree
{
void update(int x, int y)
{
while(top[x] != top[y]){
if(dep[top[x]] < dep[top[y]]) swap(x, y);
seg.reupdate(1, 1, n, id[top[x]], id[x]);
x = fa[top[x]];
}
if(dep[x] > dep[y]) swap(x, y);
seg.reupdate(1, 1, n, id[x] + 1, id[y]);
}
int querysum(int x, int y)
{
int res = 0;
while(top[x] != top[y]){
if(dep[top[x]] < dep[top[y]]) swap(x, y);
res += seg.querysum(1, 1, n, id[top[x]], id[x]);
x = fa[top[x]];
}
if(dep[x] > dep[y]) swap(x, y);
res += seg.querysum(1, 1, n, id[x] + 1, id[y]);
return res;
}
int querymaxn(int x, int y)
{
int res = INT_MIN;
while(top[x] != top[y]){
if(dep[top[x]] < dep[top[y]]) swap(x, y);
res = max(res, seg.querymaxn(1, 1, n, id[top[x]], id[x]));
x = fa[top[x]];
}
if(dep[x] > dep[y]) swap(x, y);
res = max(res, seg.querymaxn(1, 1, n, id[x] + 1, id[y]));
return res;
}
int queryminn(int x, int y)
{
int res = INT_MAX;
while(top[x] != top[y]){
if(dep[top[x]] < dep[top[y]]) swap(x, y);
res = min(res, seg.queryminn(1, 1, n, id[top[x]], id[x]));
x = fa[top[x]];
}
if(dep[x] > dep[y]) swap(x, y);
res = min(res, seg.queryminn(1, 1, n, id[x] + 1, id[y]));
return res;
}
}tp;
signed main()
{
n = read;
for(int i = 1;i < n;i ++ ){
int u = read, v = read;
u ++, v ++ ;
g[u].push_back(v), g[v].push_back(u);
cin >> w[u];
yexo[i].first = u, yexo[i].second = v;
}
dfs1(1, 0, 1), dfs2(1, 1);
seg.build(1, 1, n);
int m = read;
while(m -- ){
string s; cin >> s;
if(s == "C"){
int i = read, w = read;
int k;
if(dep[yexo[i].first] > dep[yexo[i].second]) k = yexo[i].first;
else k = yexo[i].second;
seg.update(1, 1, n, id[k], w);
}
else if(s == "N"){
int u = read, v = read;
u ++, v ++ ;
tp.update(u, v);
}
else if(s == "SUM"){
int u = read, v = read;
u ++ , v ++ ;
cout << tp.querysum(u, v) << endl;
}
else if(s == "MAX"){
int u = read, v = read;
u ++, v ++ ;
cout << tp.querymaxn(u, v) << endl;
}
else {
int u = read, v = read;
u ++ ,v ++ ;
cout << tp.queryminn(u, v) << endl;
}
}
return 0;
}
10.3 22:24 Linux