过了样例但是次次全部RE啊,好奇怪。
树剖都是对的应该,线段树啥的直接抄了板子。
讨论区看了,改了下查询的时候判断的方式,但还是RE。:(
#include <bits/stdc++.h>
using namespace std;
const int N = 1e5 + 10;
const int inf = 2e9;
struct node {
int v, w;
node (int v, int w) : v(v), w(w) {}
};
int n, m;
vector<node> g[N];
int siz[N], dep[N], fa[N], dfn[N], son[N], top[N], rnk[N], cnt, val[N];
int sum[N * 4], cov[N * 4], maxn[N * 4];
void dfs1(int u, int f) {
siz[u] = 1;
son[u] = -1;
int sz = g[u].size();
for (int i = 0; i < sz; ++i) {
int v = g[u][i].v;
if (v == f) continue;
fa[v] = u;
val[v] = g[u][i].w;
dfs1(v, u);
siz[u] += siz[v];
if (siz[son[u]] < siz[v]) son[u] = v;
}
}
void dfs2(int u, int tp) {
top[u] = tp;
dfn[u] = ++cnt;
rnk[cnt] = val[u];
if (son[u] == -1) return ;
dfs2(son[u], tp);
int sz = g[u].size();
for (int i = 0; i < sz; ++i) {
int v = g[u][i].v;
if (v == fa[u] || v == son[u]) continue;
dfs2(v, v);
}
}
void build(int l, int r, int p) {
cov[p] = -1;
if (l == r) {
maxn[p] = rnk[l];
sum[p] = 0;
return ;
}
int mid = l + r >> 1;
build(l, mid, p << 1);
build(mid + 1, r, p << 1 | 1);
maxn[p] = max(maxn[p << 1], maxn[p << 1 | 1]);
}
void pushdown(int p) {
if (~cov[p]) {
cov[p << 1] = cov[p << 1 | 1] = cov[p];
sum[p << 1] = sum[p << 1 | 1] = 0;
maxn[p << 1] = maxn[p << 1 | 1] = cov[p];
}
cov[p] = -1;
if (sum[p]) {
sum[p << 1] += sum[p], sum[p << 1 | 1] += sum[p];
maxn[p << 1] += sum[p], maxn[p << 1 | 1] += sum[p];
}
sum[p] = 0;
}
void updatecov(int l, int r, int s, int t, int c, int p) {
if (l <= s && r >= t) {
maxn[p] = c;
sum[p] = 0;
cov[p] = c;
return ;
}
pushdown(p);
int mid = s + t >> 1;
if (l <= mid) updatecov(l, r, s, mid, c, p << 1);
if (r > mid) updatecov(l, r, mid + 1, t, c, p << 1 | 1);
maxn[p] = max(maxn[p << 1], maxn[p << 1 | 1]);
}
void updatesum(int l, int r, int s, int t, int c, int p) {
if (l <= s && r >= t) {
maxn[p] += c;
sum[p] += c;
return ;
}
pushdown(p);
int mid = s + t >> 1;
if (l <= mid) updatesum(l, r, s, mid, c, p << 1);
if (r > mid) updatesum(l, r, mid + 1, t, c, p << 1 | 1);
maxn[p] = max(maxn[p << 1], maxn[p << 1 | 1]);
}
int querymax(int l, int r, int s, int t, int p) {
if (l <= s && r >= t) {
return maxn[p];
}
pushdown(p);
int mid = s + t >> 1, ans = 0;
if (l <= mid) ans = max(ans, querymax(l, r, s, mid, p << 1));
if (r > mid) ans = max(ans, querymax(l, r, mid + 1, t, p << 1 | 1));
return ans;
}
void updatecovT(int u, int v, int w) {
int ans = -inf, fu = top[u], fv = top[v];
while (fu != fv) {
if (dep[fu] >= dep[fv]) {
updatecov(dfn[fu], dfn[u], 1, n, w, 1), u = fa[fu];
} else {
updatecov(dfn[fv], dfn[v], 1, n, w, 1), v = fa[fv];
}
fu = top[u];
fv = top[v];
}
if (u == v) return ;
if (dfn[u] < dfn[v]) {
updatecov(dfn[u] + 1, dfn[v], 1, n, w, 1);
} else {
updatecov(dfn[v] + 1, dfn[u], 1, n, w, 1);
}
}
void updatesumT(int u, int v, int w) {
int ans = -inf, fu = top[u], fv = top[v];
while (fu != fv) {
if (dep[fu] >= dep[fv]) {
updatesum(dfn[fu], dfn[u], 1, n, w, 1), u = fa[fu];
} else {
updatesum(dfn[fv], dfn[v], 1, n, w, 1), v = fa[fv];
}
fu = top[u];
fv = top[v];
}
if (u == v) return ;
if (dfn[u] < dfn[v]) {
updatesum(dfn[u] + 1, dfn[v], 1, n, w, 1);
} else {
updatesum(dfn[v] + 1, dfn[u], 1, n, w, 1);
}
}
int querymaxT(int u, int v) {
int ans = -inf, fu = top[u], fv = top[v];
while (fu != fv) {
if (dep[fu] >= dep[fv]) {
ans = max(ans, querymax(dfn[fu], dfn[u], 1, n, 1)), u = fa[fu];
} else {
ans = max(ans, querymax(dfn[fv], dfn[v], 1, n, 1)), v = fa[fv];
}
fu = top[u];
fv = top[v];
}
if (u == v) return ans;
if (dfn[u] < dfn[v]) {
ans = max(ans, querymax(dfn[u] + 1, dfn[v], 1, n, 1));
} else {
ans = max(ans, querymax(dfn[v] + 1, dfn[u], 1, n, 1));
}
return ans;
}
int main() {
freopen("4315.in", "r", stdin);
freopen("4315.out", "w", stdout);
scanf("%d", &n);
for (int i = 1; i <= n - 1; ++i) {
int u, v, ww;
scanf("%d %d %d", &u, &v, &ww);
g[u].push_back({v, ww});
g[v].push_back({u, ww});
}
dfs1(1, 0);
dfs2(1, 1);
build(1, n, 1);
int u, v, w;
string s = "2";
while (s != "Stop") {
cin >> s;
if (s == "Change") {
scanf("%d %d", &u, &w);
updatecov(dfn[u] + 1, dfn[u] + 1, 1, n, w, 1);
}
if (s == "Cover") {
scanf("%d %d %d", &u, &v, &w);
updatecovT(u, v, w);
}
if (s == "Add") {
scanf("%d %d %d", &u, &v, &w);
updatesumT(u, v, w);
}
if (s == "Max") {
scanf("%d %d", &u, &v);
printf("%d\n", querymaxT(u, v));
}
}
return 0;
}