#include <bits/stdc++.h>
using namespace std;
#define REP(i, a, b) for (int i = (a), _end_ = (b); i <= _end_; ++i)
#define RREP(i, a) for (int i = first[a]; i > 0; i = next[i])
#define debug(...) fprintf(stderr,__VA_ARGS__)
#define mp make_pair
#define pb push_back
#define SZ(x) (int((x).size() - 1))
#define ALL(x) ((x).begin() + 1), (x).end()
template<typename T> inline bool chkmin(T &a,const T &b){ return a > b ? a = b, 1 : 0; }
template<typename T> inline bool chkmax(T &a,const T &b){ return a < b ? a = b, 1 : 0; }
#define next Next
typedef long long LL;
const int dmax = 100100, oo = 0x3f3f3f3f;
struct edge{
int x, y, z;
edge(){
x = y = z = 0;
}
};
edge tmp[dmax];
int n, m, N = 0;
int first[dmax], next[dmax], to[dmax], w[dmax], E;
inline void Edge(int x, int y, int z){
to[++E] = y;
w[E] = z;
next[E] = first[x];
first[x] = E;
}
inline void Tmp(int x, int y, int z){
tmp[E].x = x;
tmp[E].y = y;
tmp[E].z = z;
}
int a[dmax], d[dmax], pre[dmax], dis[dmax], top[dmax], size[dmax], rank[dmax], son[dmax];
void dfs(int x, int fa, int dep){
dis[x] = dep;
pre[x] = fa;
size[x] = 1;
RREP(i, x){
int y = to[i];
if (y != fa){
dfs(y, x, dep+1);
size[x] += size[y];
if (size[y] > size[son[x]])
son[x] = y;
}
}
}
void dfs(int x, int index){
d[x] = ++N;
top[x] = index;
if (son[x] > 0)
dfs(son[x], index);
RREP(i, x){
int y = to[i];
if (y != pre[x] && y != son[x])
dfs(y, y);
}
}
int c[dmax];
inline int Mid(int x, int y){ return (x + y) >> 1; }
inline void up(int x){ c[x] = max(c[x * 2], c[x * 2 + 1]); }
void create(int x, int l, int r){
int mid = Mid(l, r);
if (l == r){
c[x] = a[mid];
return;
}
if (l <= mid)
create(x * 2, l, mid);
if (mid+1 <= r)
create(x * 2 + 1, mid+1, r);
up(x);
}
void update(int x, int l, int r, int y, int z){
if (l == r){
c[x] = z;
return;
}
int mid = Mid(l, r);
if (y <= mid)
update(x * 2, l, mid, y, z);
else update(x * 2 + 1, mid + 1, r, y, z);
}
int query(int x, int l, int r, int s, int t){
if (l == s && r == t)
return c[x];
int mid = Mid(l, r);
if (t <= mid)
return query(x * 2, l, mid, s, t);
else{
if (s > mid)
return query(x * 2 + 1, mid + 1, r, s, t);
else{
return max(query(x * 2, l, mid, s, mid),
query(x * 2 + 1, mid + 1, r, mid + 1, t));
}
}
}
void change(int x, int y){
if (dis[tmp[x].x] < dis[tmp[x].y])
update(1, 2, n, d[tmp[x].y], y);
else update(1, 2, n, d[tmp[x].x], y);
}
int cal(int x, int y){
int ans = -oo;
while (top[x] != top[y]){
if (dis[top[x]] < dis[top[y]]) swap(x, y);
chkmax(ans, query(1, 2, n, d[top[x]], d[x]));
x = pre[top[x]];
}
if (dis[x] > dis[y]) swap(x, y);
if (x != y)
chkmax(ans, query(1, 2, n, d[x] + 1, d[y]));
return ans;
}
int main(){
#ifndef ONLINE_JUDGE
freopen("input.txt", "r", stdin);
freopen("output.txt", "w", stdout);
#endif
scanf("%d", &n);
REP(i, 1, n-1){
int x, y, z;
scanf("%d%d%d", &x, &y, &z);
Edge(x, y, z);
Tmp(x, y, z);
}
dfs(1, 1, 1);
dfs(1, 1);
REP(i, 1, n-1)
if (dis[tmp[i].x] < dis[tmp[i].y])
a[d[tmp[i].y]] = tmp[i].z;
else a[d[tmp[i].x]] = tmp[i].z;
create(1, 2, n);
scanf("%d", &m);
getchar();
REP(i, 1, m){
int q = getchar(), x, y;
scanf("%d%d", &x, &y);
getchar();
if (q == 'Q')
printf("%d\n", cal(x, y));
else change(x, y);
}
return 0;
}
树链剖分 (LCT基础)
最新推荐文章于 2022-03-15 17:39:05 发布