奇葩的代码
#include<bits/stdc++.h>
#define Scarlet_Feather return
#define AC_on_all 0
#define debug puts("-1")
#define inf 0x3f3f3f3f3f3f3f3f
#define kg putchar(' ')
#define hh putchar('\n')
//#define int long long
#define db double
#define fir first
#define sec second
#define pb push_back
#define max(a,b) (a>b?a:b)
#define min(a,b) (a<b?a:b)
#define pii pair<int,int>
#define ulp(i,a,b) for(int i=a;i<=b;++i)
#define dlp(i,a,b) for(int i=a;i>=b;--i)
#define mod 1000000007
#define il inline
using namespace std;
il int read() {
int num = 0;
bool f = 0;
char c = getchar();
while (!isdigit(c)) {
if (c == '-')f = 1;
c = getchar();
}
while (isdigit(c))num = (num << 3) + (num << 1) + (c ^ 48), c = getchar();
return f ? -num : num;
}
il void write(int x) {
if (x < 0)putchar('-'), write(-x);
else if (x < 10)putchar('0' + x);
else write(x / 10), putchar('0' + x % 10);
}
il char rdc() {
char c = getchar();
while (c == ' ' || c == '\n')c = getchar();
return c;
}
#define N 100005
vector<pii> G[N];
int fa[N], son[N], dep[N], siz[N], top[N], rev[N], dfn[N], val[N];
int n, tot;
struct path {
int u, v, w;
} P[N];
void dfs1(int u, int father) {
siz[u] = 1, fa[u] = father, dep[u] = dep[father] + 1;
for (auto[v, w] : G[u]) {
if (v != father) {
val[v] = w;
dfs1(v, u);
siz[u] += siz[v];
if (siz[v] > siz[son[u]]) {
son[u] = v;
}
}
}
}//O(n)
void dfs2(int u, int Top) {
top[u] = Top, dfn[u] = ++tot, rev[tot] = u;
if (!son[u])return ;
dfs2(son[u], Top);
for (auto[v, w] : G[u]) {
if (v != fa[u] && v != son[u]) {
dfs2(v, v);
}
}
}//O(n)
#define ls (pos<<1)
#define rs ((pos<<1)|1)
int tr[N << 2], lazy_add[N << 2], lazy_cover[N << 2];
il void push_up(int pos) {
tr[pos] = max(tr[ls], tr[rs]);
}//O(1)
il void push_down(int pos) {
if (lazy_cover[pos] != -1) {
tr[ls] = tr[rs] = lazy_cover[pos];
lazy_cover[ls] = lazy_cover[rs] = lazy_cover[pos];
lazy_add[ls] = lazy_add[rs] = 0;
lazy_cover[pos] = -1;
}
if (lazy_add[pos]) {
tr[ls] += lazy_add[pos];
tr[rs] += lazy_add[pos];
lazy_add[ls] += lazy_add[pos];
lazy_add[rs] += lazy_add[pos];
lazy_add[pos] = 0;
}
}//O(1)
void build(int pos, int l, int r) {
lazy_add[pos] = 0;
lazy_cover[pos] = -1;
if (l == r) {
tr[pos] = val[rev[l]];
return ;
}
int mid = (l + r) >> 1;
build(ls, l, mid);
build(rs, mid + 1, r);
push_up(pos);
}//O(n)
il void update_change(int pos, int l, int r, int target, int v) {
if (l == r) {
tr[pos] = v;
return ;
}
push_down(pos);
int mid = (l + r) >> 1;
if (target <= mid)update_change(ls, l, mid, target, v);
else update_change(rs, mid + 1, r, target, v);
push_up(pos);
}//O(logn)
il void update_add(int pos, int l, int r, int x, int y, int v) {
if (l >= x && r <= y) {
tr[pos] += v;
lazy_add[pos] += v;
return ;
}
push_down(pos);
int mid = (l + r) >> 1;
if (x <= mid)update_add(ls, l, mid, x, y, v);
if (y > mid)update_add(rs, mid + 1, r, x, y, v);
push_up(pos);
}//O(logn)
il void update_cover(int pos, int l, int r, int x, int y, int v) {
if (l >= x && r <= y) {
tr[pos] = v;
lazy_cover[pos] = v;
lazy_add[pos] = 0;
return ;
}
push_down(pos);
int mid = (l + r) >> 1;
if (x <= mid)update_cover(ls, l, mid, x, y, v);
if (y > mid)update_cover(rs, mid + 1, r, x, y, v);
push_up(pos);
}//O(logn)
il int query(int pos, int l, int r, int x, int y) {
if (l >= x && r <= y) {
return tr[pos];
}
push_down(pos);
int mid = (l + r) >> 1, ans = 0;
if (x <= mid)ans = query(ls, l, mid, x, y);
if (y > mid)ans = max(ans, query(rs, mid + 1, r, x, y));
return ans;
}//O(logn)
#undef ls
#undef rs
void update_on_tree_add(int x, int y, int v) {
if (x == y)return ;
while (top[x] != top[y]) {
if (dep[top[y]] > dep[top[x]])swap(x, y);
update_add(1, 1, n, dfn[top[x]], dfn[x], v);
x = fa[top[x]];
}
if (dep[y] > dep[x]) swap(x, y);
update_add(1, 1, n, dfn[y] + 1, dfn[x], v);
}//O(log^2n)
void update_on_tree_cover(int x, int y, int v) {
if (x == y)return ;
while (top[x] != top[y]) {
if (dep[top[y]] > dep[top[x]])swap(x, y);
update_cover(1, 1, n, dfn[top[x]], dfn[x], v);
x = fa[top[x]];
}
if (dep[y] > dep[x]) swap(x, y);
update_cover(1, 1, n, dfn[y] + 1, dfn[x], v);
}//O(log^2n)
int query_on_tree(int x, int y) {
if (x == y)return 0;
int ans = 0;
while (top[x] != top[y]) {
if (dep[top[y]] > dep[top[x]])swap(x, y);
ans = max(ans, query(1, 1, n, dfn[top[x]], dfn[x]));
x = fa[top[x]];
}
if (dep[y] > dep[x]) swap(x, y);
ans = max(ans, query(1, 1, n, dfn[y] + 1, dfn[x]));
return ans;
}//O(log^2n)
signed main() {
n = read();
ulp(i, 1, n - 1) {
int u = read(), v = read(), w = read();
G[u].pb({v, w}), G[v].pb({u, w});
P[i] = {u, v, w};
}
dfs1(1, 0);
dfs2(1, 1);
build(1, 1, n);
while (true) {
char op = rdc();
if (op == 'S')break;
switch (op) {
case 'M': {
int u = read(), v = read();
write(query_on_tree(u, v));
hh;
break;
}
case 'A': {
int u = read(), v = read(), w = read();
update_on_tree_add(u, v, w);
break;
}
default: {
op = rdc();
if (op == 'h') {
int k = read(), w = read();
auto [u, v, W] = P[k];
if (dep[u] < dep[v])swap(u, v);
update_change(1, 1, n, dfn[u], w);
} else {
int u = read(), v = read(), w = read();
update_on_tree_cover(u, v, w);
}
break;
}
}
}
return 0;
}