题目链接
裸树链剖分。要求维护一棵树,支持修改某条树边的长度以及查询两点间距离。
闲话少叙,直接上代码。
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
const int N = 100010;
struct edge {
int v, w, id, nxt;
}lib[N<<1];//据说std::vector会TLE
int mapHead[N], mapTot = 0;
inline void ins(int u, int v, int w, int id) {
lib[mapTot] = (edge) {v, w, id, mapHead[u]};
mapHead[u] = mapTot++;
}
int size[N], dep[N], son[N], fa[N], top[N], seg[N], tn[N], segCnt;
int pos[N], val[N];
void dfs1(int u, int f) {
fa[u] = f; size[u] = 1; dep[u] = dep[f] + 1;
for (int i = mapHead[u]; i != -1; i = lib[i].nxt) {
int &v = lib[i].v, &w = lib[i].w, &id = lib[i].id;
if (v == f) continue;
dfs1(v, u);
if (size[son[u]] < size[v])
son[u] = v;
size[u] += size[v];
val[pos[id] = v] = w;
}
}
void dfs2(int u, int tp) {
top[u] = tp; seg[u] = ++segCnt, tn[seg[u]] = u;
if (! son[u]) return;
dfs2(son[u], tp);
for (int i = mapHead[u]; i != -1; i = lib[i].nxt) {
int &v = lib[i].v;
if (v == fa[u] || v == son[u]) continue;
dfs2(v, v);
}
}
int tree[N<<1];
#define g(l, r) (l + r | l != r)
#define o g(l, r)
#define ls g(l, mid)
#define rs g(mid + 1, r)
int gl, gr, gx;
#define set(l, r, x) gl = l, gr = r, gx = x;
inline void update(int l, int r) {
int mid = l + r >> 1;
tree[o] = tree[ls] + tree[rs];
}
void buildTree(int l, int r) {
if (l == r) {
tree[o] = val[tn[l]];
return;
}
int mid = l + r >> 1;
buildTree(l, mid);
buildTree(mid + 1, r);
update(l, r);
}
int n, q, s;
void query(int l, int r) {
if (gl <= l && r <= gr) {
gx += tree[o]; return;
}
int mid = l + r >> 1;
if (gl <= mid) query(l, mid);
if (mid + 1 <= gr) query(mid + 1, r);
}
inline void Query(int u, int v) {
int f1 = top[u], f2 = top[v]; gx = 0;
while (f1 != f2) {
if (dep[f1] < dep[f2]) {
swap(u, v); swap(f1, f2);
}
set(seg[f1], seg[u], gx); query(1, n);
u = fa[f1]; f1 = top[u];
}
if (dep[u] < dep[v]) swap(u, v);
set(seg[v], seg[u], gx); query(1, n);
printf("%d\n", gx - val[v]);
}
void modify(int l, int r) {
if (l == r) {
tree[o] = gx;
return;
}
int mid = l + r >> 1;
if (gl <= mid) modify(l, mid);
else modify(mid + 1, r);
update(l, r);
}
inline void Modify(int x, int w) {
set(x, x, w);
modify(1, n);
}
int main() {
cin >> n >> q >> s;
memset(mapHead, 0xff, sizeof(mapHead));
for (int i = 1; i < n; i++) {
int u, v, w; scanf("%d%d%d", &u, &v, &w);
ins(u, v, w, i); ins(v, u, w, i);
}
dfs1(1, 0);
dfs2(1, 1);
buildTree(1, n);
while (q--) {
int t, x; scanf("%d%d", &t, &x);
if (t == 0) {
Query(x, s); s = x;
} else {
int w; scanf("%d", &w);
Modify(seg[pos[x]], w);
val[pos[x]] = w;
}
}
return 0;
}