尸体

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
*/
posted @ 2026-02-22 11:53  yabnto  阅读(8)  评论(0)    收藏  举报