尸体
P14829 [THUPC 2026 初赛] Asian Soul
笑死最后发现空间不够
#include <iostream>
#include <vector>
#include <cmath>
#include <algorithm>
#include <map>
using namespace std;
const int MaxN = 10000 + 10, MaxK = 20, MaxB = 707;
int f[MaxB][MaxN][MaxK], d[MaxB][MaxN << 2], sz[MaxB][MaxN], son[MaxB][MaxN], dfn[MaxB][MaxN], val[MaxB][MaxN], gfa[MaxB][MaxN], dep[MaxB][MaxN], top[MaxB][MaxN], a[MaxN], p[MaxN], L[MaxN], R[MaxN], topa[MaxN], b[MaxN], st[MaxN], cnt, tot, n, m, q, B;
vector<int> g[MaxB][MaxN];
map<int, int> fff[MaxN];
void modify(int flag, int k, int w, int l = 1, int r = n, int p = 1) {
if (l == r) {
d[flag][p] = w;
return;
}
int mid = l + r >> 1;
if (k <= mid) modify(flag, k, w, l, mid, p << 1);
if (k > mid) modify(flag, k, w, mid + 1, r, p << 1 | 1);
d[flag][p] = max(d[flag][p << 1], d[flag][p << 1 | 1]);
}
int query(int flag, int pl, int pr, int l = 1, int r = n, int p = 1) {
if (pl <= l && r <= pr) return d[flag][p];
if (pl > r || pr < l) return -1e9;
int mid = l + r >> 1;
return max(query(flag, pl, pr, l, mid, p << 1), query(flag, pl, pr, mid + 1, r, p << 1 | 1));
}
void DFS(int x, int flag, int fa = 0) {
sz[flag][x] = 1, gfa[flag][x] = fa, dep[flag][x] = dep[flag][fa] + 1, f[flag][x][0] = fa ? fa : 1;
for (int i = 1; i < MaxK; i++) {
f[flag][x][i] = f[flag][f[flag][x][i - 1]][i - 1];
}
for (int i : g[flag][x]) {
if (i == fa) continue;
DFS(i, flag, x), sz[flag][x] += sz[flag][i], (sz[flag][son[flag][x]] < sz[flag][i]) && (son[flag][x] = i);
}
}
void S(int x, int flag, int fa = 0, int to = 1) {
dfn[flag][x] = ++tot, val[flag][dfn[flag][x]] = x, top[flag][x] = to, modify(flag, dfn[flag][x], val[flag][dfn[flag][x]]), fff[x][flag] = 0;
if (son[flag][x]) S(son[flag][x], flag, x, to);
for (int i : g[flag][x]) {
if (i == fa || i == son[flag][x]) continue;
S(i, flag, x, i);
}
}
int goyt(int flag, int x, int k) {
for (int i = MaxK - 1; i >= 0; i--) {
if (k & (1 << i)) x = f[flag][x][i];
}
return x;
}
int LCA(int flag, int x, int y) {
if (dep[flag][x] < dep[flag][y]) swap(x, y);
x = goyt(flag, x, dep[flag][x] - dep[flag][y]);
if (x == y) return x;
for (int i = MaxK - 1; i >= 0; i--) {
if (f[flag][x][i] != f[flag][y][i]) x = f[flag][x][i], y = f[flag][y][i];
}
return f[flag][x][0];
}
void initA() {
B = sqrt(m);
for (int i = 1; i <= m; i++) {
p[i] = i / B + 1, L[p[i]] = (L[p[i]] ? L[p[i]] : i), R[p[i]] = i;
}
}
void build(int flag, int l, int r, int p) {
for (int i = l; i <= r; i++) {
b[i - l + 1] = a[i];
}
int tm = (r - l + 1);
sort(b + 1, b + tm + 1, [](int i, int j) {
return dfn[0][i] < dfn[0][j];
});
cnt = 0, st[++cnt] = p;
tm = unique(b + 1, b + tm + 1) - b - 1;
for (int i = 1, l; i <= tm; i++) {
if (b[i] == p) continue;
l = LCA(0, b[i], st[cnt]);
if (l != st[cnt]) {
while (dfn[0][l] < dfn[0][st[cnt - 1]]) {
g[flag][st[cnt - 1]].push_back(st[cnt]), g[flag][st[cnt]].push_back(st[cnt - 1]);
cnt--;
}
if (dfn[0][l] > dfn[0][st[cnt - 1]]) {
g[flag][l].push_back(st[cnt]), g[flag][st[cnt]].push_back(l);
st[cnt] = l;
} else {
int t = st[cnt--];
g[flag][l].push_back(t), g[flag][t].push_back(l);
}
}
st[++cnt] = b[i];
}
for (int i = 1; i < cnt; i++) {
g[flag][st[i]].push_back(st[i + 1]), g[flag][st[i + 1]].push_back(st[i]);
}
}
int queryt(int flag, int x, int y, int res = 0) {
while (top[flag][x] != top[flag][y]) {
if (dep[flag][top[flag][x]] < dep[flag][top[flag][y]]) swap(x, y);
res = max(res, query(1, dfn[flag][top[flag][x]], dfn[flag][x]));
x = gfa[flag][top[flag][x]];
}
if (dep[flag][x] < dep[flag][y]) swap(x, y);
return max(res, query(flag, dfn[flag][y], dfn[flag][x]));
}
int Work(int flag, int g, int x) {
int tp = topa[g];
if (dfn[0][tp] <= dfn[0][x] && dfn[0][x] <= dfn[0][tp] + sz[0][tp] - 1) { // 在该树内
while (!fff[x].count(flag)) {
x = gfa[0][x];
}
return queryt(flag, x, tp);
} else {
return LCA(0, tp, x);
}
}
int queryA(int l, int r, int x) {
if (p[l] == p[r]) {
int maxx = 0;
for (int i = l; i <= r; i++) {
maxx = max(maxx, LCA(0, a[i], x));
}
return maxx;
}
int maxx = 0;
for (int i = l; i <= R[p[l]]; i++) {
maxx = max(maxx, LCA(0, a[i], x));
}
for (int i = L[p[r]]; i <= r; i++) {
maxx = max(maxx, LCA(0, a[i], x));
}
for (int i = p[l] + 1; i < p[r]; i++) {
maxx = max(maxx, Work(i, i, x));
}
return maxx;
}
int main() {
cin >> n >> m >> q;
for (int i = 1, u, v; i < n; i++) {
cin >> u >> v;
g[0][u].push_back(v);
g[0][v].push_back(u);
}
DFS(1, 0), S(1, 0), tot = 0;
for (int i = 1; i <= m; i++) {
cin >> a[i];
}
initA();
for (int i = 1, l; i <= p[m]; i++) {
l = a[L[i]];
for (int j = L[i] + 1; j <= R[i]; j++) {
l = LCA(0, l, a[j]);
}
topa[i] = l;
build(i, L[i], R[i], l), DFS(l, i), S(l, i), tot = 0;
}
for (int l, r, x; q; q--) {
cin >> l >> r >> x;
cout << queryA(l, r, x) << endl;
}
return 0;
}
/*
1 2 3 4 5 6 7 8 9 10 11 12
10 8 6 4 3 2 5 7 1 4 6 7
*/

浙公网安备 33010602011771号