洛谷P14989 传送 题解 笛卡尔树+LCA
题目链接:https://www.luogu.com.cn/problem/P14989
解题思路完全来自 elainya_stars 大佬的博客
示例程序:
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
const ll mod = 1e9 + 7;
const int maxn = 5e5 + 5;
int n, Q, a[maxn], ls[maxn], rs[maxn], fa[maxn][19], dep[maxn];
void dfs(int u, int d) {
dep[u] = d;
if (ls[u]) {
fa[ ls[u] ][0] = u;
dfs(ls[u], d+1);
}
if (rs[u]) {
fa[ rs[u] ][0] = u;
dfs(rs[u], d+1);
}
}
int lca(int x, int y) {
if (dep[x] < dep[y]) swap(x, y);
for (int i = 18; i >= 0; i--) {
if (dep[ fa[x][i] ] >= dep[y])
x = fa[x][i];
}
if (x == y) return x;
for (int i = 18; i >= 0; i--) {
if (fa[x][i] != fa[y][i]) {
x = fa[x][i];
y = fa[y][i];
}
}
return fa[x][0];
}
int main() {
scanf("%d%d", &n, &Q);
for (int i = 1; i <= n; i++)
scanf("%d", a+i);
stack<int> stk;
for (int i = 1; i <= n; i++) {
int last = 0;
while (!stk.empty() && a[stk.top()] < a[i]) {
last = stk.top();
stk.pop();
}
if (!stk.empty()) rs[stk.top()] = i;
ls[i] = last;
stk.push(i);
}
int rt;
do {
rt = stk.top();
stk.pop();
} while (!stk.empty());
dfs(rt, 1);
for (int i = 1; i <= 18; i++)
for (int u = 1; u <= n; u++)
fa[u][i] = fa[ fa[u][i-1] ][i-1];
while (Q--) {
int k, x, y;
scanf("%d%d", &k, &x);
for (int i = 1; i < k; i++) {
scanf("%d", &y);
x = lca(x, y);
}
printf("%d\n", dep[x]);
}
return 0;
}
浙公网安备 33010602011771号