rt,已看警钟。
https://www.luogu.com.cn/record/182007315
# include <bits/stdc++.h>
# define I return
# define AK 0
# define IOI ;
using namespace std;
typedef long long ll;
typedef pair <int, int> pii;
struct node {
int x, w, id;
} ;
int n, mp[100005], s[100005], heavist[100005], x, y, tot, dfn[100005], maxx[400005], cover[400005], add[400005], a[100005], b[100005], k, st[100005], depth[100005], f[100005];
string op;
vector <node> v[100005];
void init1 (const int x, const int fa) {
s[x] = 1, f[x] = fa;
depth[x] = depth[fa] + 1;
for (const node& i : v[x])
if (i.x != fa) {
b[i.x] = i.w, mp[i.id] = i.x;
init1 (i.x, x);
s[x] += s[i.x];
if (s[heavist[x]] < s[i.x])
heavist[x] = i.x;
}
return ;
}
void init2 (const int x, const int fa, const int s) {
a[dfn[x] = ++ tot] = b[x], st[x] = s;
if (! heavist[x])
return ;
init2 (heavist[x], x, s);
for (const node& i : v[x])
if (i.x != fa && i.x != heavist[x])
init2 (i.x, x, i.x);
return ;
}
void build (const int x, const int l, const int r) {
cover[x] = -1;
if (l == r) {
maxx[x] = a[l];
return ;
}
const int mid = l + r >> 1, left = x << 1, right = left | 1;
build (left, l, mid), build (right, mid + 1, r);
maxx[x] = max (maxx[left], maxx[right]);
return ;
}
void pushdown (const int x, const int left, const int right) {
if (~cover[x])
maxx[left] = maxx[right] = cover[left] = cover[right] = cover[x], add[left] = add[right] = 0, cover[x] = -1;
else if (add[x])
maxx[left] += add[x], maxx[right] += add[x], add[left] += add[x], add[right] += add[x], add[x] = 0;
return ;
}
void Cover (const int x, const int l, const int r, const int L, const int R) {
if (l == L && r == R) {
maxx[x] = cover[x] = k, add[x] = 0;
return ;
}
const int mid = l + r >> 1, left = x << 1, right = left | 1;
pushdown (x, left, right);
if (R <= mid)
Cover (left, l, mid, L, R);
else if (L > mid)
Cover (right, mid + 1, r, L, R);
else
Cover (left, l, mid, L, mid), Cover (right, mid + 1, r, mid + 1, R);
maxx[x] = max (maxx[left], maxx[right]);
return ;
}
void Add (const int x, const int l, const int r, const int L, const int R) {
if (l == L && r == R) {
maxx[x] += k;
if (~cover[x])
cover[x] += k;
else
add[x] += k;
return ;
}
const int mid = l + r >> 1, left = x << 1, right = left | 1;
pushdown (x, left, right);
if (R <= mid)
Add (left, l, mid, L, R);
else if (L > mid)
Add (right, mid + 1, r, L, R);
else
Add (left, l, mid, L, mid), Add (right, mid + 1, r, mid + 1, R);
maxx[x] = max (maxx[left], maxx[right]);
return ;
}
int find (const int x, const int l, const int r, const int L, const int R) {
// cerr << L << '~' << R << ':' << x << ':' << l << '~' << r << '\n';
if (l == L && r == R)
return maxx[x];
const int mid = l + r >> 1, left = x << 1, right = left | 1;
pushdown (x, left, right);
if (R <= mid)
return find (left, l, mid, L, R);
if (L > mid)
return find (right, mid + 1, r, L, R);
return max (find (left, l, mid, L, mid), find (right, mid + 1, r, mid + 1, R));
}
void Change (const int x) {
Cover (1, 1, n, dfn[mp[x]], dfn[mp[x]]);
return ;
}
void Cover (int x, int y) {
while (st[x] ^ st[y]) {
if (depth[st[x]] < depth[st[y]])
swap (x, y);
Cover (1, 1, n, dfn[st[x]], dfn[x]);
x = f[st[x]];
}
if (dfn[x] > dfn[y])
swap (x, y);
if (dfn[x]^dfn[y])
Cover (1, 1, n, dfn[x] + 1, dfn[y]);
return ;
}
void Add (int x, int y) {
while (st[x] ^ st[y]) {
if (depth[st[x]] < depth[st[y]])
swap (x, y);
Add (1, 1, n, dfn[st[x]], dfn[x]);
x = f[st[x]];
}
if (dfn[x] > dfn[y])
swap (x, y);
if (dfn[x]^dfn[y])
Add (1, 1, n, dfn[x] + 1, dfn[y]);
return ;
}
int Max (int x, int y) {
int maxx = 0;
while (st[x] ^ st[y]) {
if (depth[st[x]] < depth[st[y]])
swap (x, y);
// cerr << x << '~' << y << ':' << st[x] << '~' << x << ':' << dfn[st[x]] << '~' << dfn[x] << '\n';
maxx = max (maxx, find (1, 1, n, dfn[st[x]], dfn[x]));
x = f[st[x]];
}
if (dfn[x] > dfn[y])
swap (x, y);
if (dfn[x]^dfn[y])
maxx = max (maxx, find (1, 1, n, dfn[x] + 1, dfn[y]));
return maxx;
}
int main () {
ios::sync_with_stdio (0);
cin.tie (0);
cout.tie (0);
cin >> n;
for (int i = 1; i < n; ++ i)
cin >> x >> y >> k, v[x].push_back ({y, k, i}), v[y].push_back ({x, k, i});
init1 (1, 0), init2 (1, 0, 1);
build (1, 1, n);
while (cin >> op, op[0]^'S')
if (op[0] == 'M') //cerr << "\n111\n",
cin >> x >> y, cout << Max (x, y) << '\n';
else if (op[0] == 'A')
cin >> x >> y >> k, Add (x, y);
else if (op[1] == 'h')
cin >> x >> k, Change (x);
else
cin >> x >> y >> k, Cover (x, y);
I AK IOI
}
/*
6
1 2 7
1 3 5
1 4 3
3 5 1
3 6 2
Ch 4 8
Ma 3 5
Ma 2 5
Co 2 5 10
Ma 2 4
Ma 2 6
Ma 3 6
Ma 5 6
Ad 1 4 51
Ma 5 4
Ma 1 5
Stop
8
8
10
10
2
10
54
10
*/