倍增求LCA

#include <bits/stdc++.h>
#define ll long long
#define ull unsigned long long
#define rep(i,a,b) for(ll i=(a);i<=(b);i++)
#define dec(i,a,b) for(ll i=(a);i>=(b);i--)
#define pll pair<ll,ll>
using namespace std;
ll INF = 0x7f7f7f7f7f7f7f7f;
const int N = 5e5 + 5;
ll mod = 1e9;

ll lg[N],d[N];
ll n, m, s;
vector<ll> g[N];
ll f[N][21];
void dfs(ll x, ll fa) {
    d[x] = d[fa] + 1;
    f[x][0] = fa;
    rep(i, 1, lg[d[x]]) {
        f[x][i] = f[f[x][i - 1]][i - 1];
    }
    for (auto to : g[x]) {
        if (to == fa) continue;
        dfs(to, x);
    }
}
ll lca(ll x, ll y) {
    if (d[x] < d[y])
        swap(x, y);
    while (d[x] > d[y])
        x = f[x][lg[d[x] - d[y]]];
    if (x == y)
        return x;
    dec(k, lg[d[x]], 0) {
        if (f[x][k] != f[y][k])
            x = f[x][k], y = f[y][k];
    }
    return f[x][0];
}
int main() {
#ifdef _DEBUG
    freopen("input.txt", "r", stdin);
    //freopen("output.txt", "w", stdout);
#endif
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    cin >> n >> m >> s;
    lg[0] = -1;
    rep(i, 1, N - 1) {
        lg[i] = lg[i / 2] + 1;
    }
    rep(i, 1, n - 1) {
        ll u, v;
        cin >> u >> v;
        g[u].push_back(v);
        g[v].push_back(u);
    }
    dfs(s, 0);
    while (m--) {
        ll x, y;
        cin >> x >> y;
        cout << lca(x, y) << '\n';
    }
    return 0;
}

 

posted @ 2022-02-01 21:00  DeaL57  阅读(22)  评论(0编辑  收藏  举报