2021.3.31
\(\mathcal{A}\)
#include <bits/stdc++.h>
using namespace std;
namespace cxcyl {
const int N = (40000 + 5) << 2;
struct Info {
int t, x, l, r;
} c[N];
struct Query {
int x, y, i;
} d[N];
struct Plate {
int a, b, c;
} p[N];
struct Fruit {
int u, v, k;
} f[N];
int n, P, Q, dfn[N], tif[N], s[N], ans[N], id[N], timer, ret[N], you[N], to[N], fa[N][21];
vector<int> G[N];
inline int read() {
int x = 0, f = 1; char c = getchar();
while (c > -1 && c < '0' || c > '9') { if (c == '-') f = -1; c = getchar(); }
if (c == -1) return 0;
while (c >= '0' && c <= '9') x = x * 10 + c - 48, c = getchar();
return x * f;
}
void dfs(int u) {
dfn[u] = ++timer;
for (int j = 1; j <= 20; ++j)
fa[u][j] = fa[fa[u][j - 1]][j - 1];
for (int v : G[u])
if (v != fa[u][0]) {
fa[v][0] = u;
dfs(v);
}
tif[u] = timer;
}
inline void R(int x, int y) {
for (; x <= n; x += x & -x) s[x] += y;
}
inline int A(int x) {
int y = 0;
for (; x; x -= x & -x) y += s[x];
return y;
}
void solve(int pl, int pr, int fl, int fr) {
if (fl > fr) return;
if (pl == pr) {
for (int i = fl; i <= fr; ++i) {
assert(f[id[i]].k == 1);
ans[id[i]] = p[pl].c;
}
return;
}
int mid = pl + pr >> 1, cnt = 0, dcnt = 0;
for (int i = pl; i <= mid; ++i)
if (p[i].a == p[i].b) {
c[++cnt] = (Info){0, 1, dfn[p[i].b], tif[p[i].b]};
c[++cnt] = (Info){1, dfn[p[i].a] + 1, dfn[p[i].b], tif[p[i].b]};
c[++cnt] = (Info){0, tif[p[i].a] + 1, dfn[p[i].b], tif[p[i].b]};
c[++cnt] = (Info){1, n + 1, dfn[p[i].b], tif[p[i].b]};
} else if (dfn[p[i].a] <= dfn[p[i].b] && dfn[p[i].b] <= tif[p[i].a]) {
c[++cnt] = (Info){0, 1, dfn[p[i].b], tif[p[i].b]};
c[++cnt] = (Info){1, dfn[to[i]], dfn[p[i].b], tif[p[i].b]};
c[++cnt] = (Info){0, tif[to[i]] + 1, dfn[p[i].b], tif[p[i].b]};
c[++cnt] = (Info){1, n + 1, dfn[p[i].b], tif[p[i].b]};
} else {
c[++cnt] = (Info){0, dfn[p[i].a], dfn[p[i].b], tif[p[i].b]};
c[++cnt] = (Info){1, tif[p[i].a] + 1, dfn[p[i].b], tif[p[i].b]};
}
sort(c + 1, c + cnt + 1, [](Info x, Info y) {
return x.x < y.x || x.x == y.x && x.t < y.t; });
for (int i = fl; i <= fr; ++i) {
ret[i] = 0;
d[++dcnt] = (Query){dfn[f[id[i]].u], dfn[f[id[i]].v], i};
d[++dcnt] = (Query){dfn[f[id[i]].v], dfn[f[id[i]].u], i};
}
sort(d + 1, d + dcnt + 1, [](Query x, Query y) { return x.x < y.x; });
for (int i = 1, u = 1, j; i <= cnt; ) {
for (j = i; j <= cnt && c[j].t == c[i].t && c[j].x == c[i].x; ++j) {
if (c[j].t == 0) {
R(c[j].l, 1);
R(c[j].r + 1, -1);
} else {
R(c[j].l, -1);
R(c[j].r + 1, 1);
}
}
while (u <= dcnt && d[u].x < c[i].x) ++u;
for (; u <= dcnt && d[u].x < c[j].x; ++u)
ret[d[u].i] += A(d[u].y);
i = j;
}
int zhi = fl - 1, ycnt = 0;
for (int i = fl; i <= fr; ++i)
if (ret[i] < f[id[i]].k) {
you[++ycnt] = id[i];
f[id[i]].k -= ret[i];
} else
id[++zhi] = id[i];
for (int i = zhi + 1; i <= fr; ++i)
id[i] = you[i - zhi];
solve(pl, mid, fl, zhi);
solve(mid + 1, pr, zhi + 1, fr);
}
inline int main() {
n = read(), P = read(), Q = read();
for (int i = 1; i < n; ++i) {
int u = read(), v = read();
G[u].push_back(v);
G[v].push_back(u);
}
dfs(1);
for (int i = 1; i <= P; ++i) {
p[i].a = read(), p[i].b = read(), p[i].c = read();
if (dfn[p[i].a] > dfn[p[i].b]) swap(p[i].a, p[i].b);
}
for (int i = 1; i <= Q; ++i) {
f[i].u = read(), f[i].v = read(), f[i].k = read();
id[i] = i;
}
sort(p + 1, p + P + 1, [](Plate x, Plate y) { return x.c < y.c; });
for (int i = 1; i <= P; ++i) {
to[i] = p[i].b;
for (int j = 20; j >= 0; --j)
if (dfn[fa[to[i]][j]] > dfn[p[i].a])
to[i] = fa[to[i]][j];
}
solve(1, P, 1, Q);
for (int i = 1; i <= Q; ++i) printf("%d\n", ans[i]);
return 0;
}
} int main() { return cxcyl::main(); }