以下是AC代码:
#include <iostream>
#include <vector>
#include <stack>
#include <random>
using namespace std;
const int maxN = 1e5 + 5;
random_device seed;
mt19937 rd(seed());
vector<int> E[maxN];
int n, dep[maxN], f[maxN], top[maxN], sz[maxN], son[maxN], in[maxN], sign;
int w[maxN], c[maxN];
int rt[maxN];
struct Treap {
int tot, sum[maxN], ch[maxN][2], pro[maxN], val[maxN], maxx[maxN], p[maxN];
stack<int> st;
void pushup(int x) {
maxx[x] = max(max(maxx[ch[x][0]], maxx[ch[x][1]]), p[x]);
sum[x] = sum[ch[x][0]] + sum[ch[x][1]] + p[x];
}
int newnode(int x, int y) {
int k;
if (!st.empty()) k = st.top(), st.pop();
else k = ++tot;
val[k] = x;
sum[k] = maxx[k] = p[k] = y;
pro[k] = (int) rd();
return k;
}
void split(int &cur, int key, int &l, int &r) {
if (!cur) return l = r = 0, void();
if (val[cur] <= key) split(ch[cur][1], key, ch[l = cur][1], r);
else split(ch[cur][0], key, l, ch[r = cur][0]);
pushup(cur);
}
int merge(int u, int v) {
if (!u || !v) return u | v;
if (pro[u] < pro[v]) return ch[u][1] = merge(ch[u][1], v), pushup(u), u;
else return ch[v][0] = merge(u, ch[v][0]), pushup(v), v;
}
void ins(int x, int y, int z) {
int l, r;
split(rt[x], y, l, r);
rt[x] = merge(merge(l, newnode(y, z)), r);
}
void del(int x, int y) {
int l, r, mid;
split(rt[x], y, l, r);
split(l, y - 1, l, mid);
rt[x] = merge(merge(l, merge(ch[mid][0], ch[mid][1])), r);
ch[mid][0] = ch[mid][1] = 0;
sum[mid] = val[mid] = pro[mid] = maxx[mid] = 0;
st.push(mid);
}
int querySum(int x, int L, int R) {
int l, mid, r;
split(rt[x], L - 1, l, mid);
split(mid, R, mid, r);
int res = sum[mid];
rt[x] = merge(merge(l, mid), r);
return res;
}
int queryMaxx(int x, int L, int R) {
int l, mid, r;
split(rt[x], L - 1, l, mid);
split(mid, R, mid, r);
int res = maxx[mid];
rt[x] = merge(merge(l, mid), r);
return res;
}
} tr;
void Dfs1(int u, int fa) {
f[u] = fa;
dep[u] = dep[fa] + 1;
sz[u] = 1;
for (auto i: E[u]) {
int v = i;
if (v == fa) continue;
Dfs1(v, u);
sz[u] += sz[v];
if (sz[son[u]] < sz[v]) son[u] = v;
}
}
void Dfs2(int u, int sp) {
top[u] = sp;
in[u] = ++sign;
if (son[u]) Dfs2(son[u], sp);
for (auto i: E[u]) {
int v = i;
if (v == f[u] || v == son[u]) continue;
Dfs2(v, v);
}
}
int TcquerySum(int root, int u, int v) {
int ans = 0;
while (top[u] != top[v]) {
if (dep[top[u]] < dep[top[v]]) swap(u, v);
ans += tr.querySum(root, in[top[u]], in[u]);
u = f[top[u]];
}
if (dep[u] > dep[v]) swap(u, v);
ans += tr.querySum(root, in[u], in[v]);
return ans;
}
int TcqueryMaxx(int root, int u, int v) {
int ans = 0;
while (top[u] != top[v]) {
if (dep[top[u]] < dep[top[v]]) swap(u, v);
ans = max(ans, tr.queryMaxx(root, in[top[u]], in[u]));
u = f[top[u]];
}
if (dep[u] > dep[v]) swap(u, v);
ans = max(ans, tr.queryMaxx(root, in[u], in[v]));
return ans;
}
int main() {
#ifdef LOCAL
freopen("test.in", "r", stdin);
freopen("test.out", "w", stdout);
#endif
ios_base::sync_with_stdio(false);
cin.tie(nullptr), cout.tie(nullptr);
int q;
cin >> n >> q;
for (int i = 1; i <= n; ++i) cin >> w[i] >> c[i];
for (int i = 1; i < n; ++i) {
int u, v;
cin >> u >> v;
E[u].emplace_back(v);
E[v].emplace_back(u);
}
Dfs1(1, 0);
Dfs2(1, 1);
for (int i = 1; i <= n; ++i) tr.ins(c[i], in[i], w[i]);
while (q--) {
char op;
int x, y;
cin >> op >> op >> x >> y;
if (op == 'C') {
tr.del(c[x], in[x]);
tr.ins(c[x] = y, in[x], w[x]);
} else if (op == 'W') {
tr.del(c[x], in[x]);
tr.ins(c[x], in[x], w[x] = y);
} else if (op == 'S') {
cout << TcquerySum(c[x], x, y) << '\n';
} else {
cout << TcqueryMaxx(c[x], x, y) << '\n';
}
}
return 0;
}
但是!把querySum和queryMaxx函数中的两个split改成以下:
split(rt[x], R, l, r);
split(l, L - 1, l, mid);
就会WA,这两个不是一个意思吗??
蒟蒻不理解,求大佬解释,感激不尽!