倍增树剖30pts,求hack数据
查看原帖
倍增树剖30pts,求hack数据
122298
Azote楼主2023/10/11 01:03
#include <iostream>
#include <cstdio>

const int N = 5e5 + 5, M = 5e5 + 5;

int head[N], nxt[M * 2], to[M * 2], cnt = 0;

void add(int u, int v)
{
    nxt[++cnt] = head[u];
    head[u] = cnt;
    to[cnt] = v;
    return;
}

int n, m, root;

int fa[N], anc[N][32], dep[N], size[N], bigs[N], top[N], id[N], deptop[N];

int cnt2 = 0;

void dfs1(int u, int f)
{
    fa[u] = f;
    dep[u] = dep[f] + 1;
    size[u] = 1;
    bigs[u] = 0;
    for (int i = head[u]; i; i = nxt[i])
    {
        if (to[i] == f)
            continue;
        dfs1(to[i], u);
        size[u] += size[to[i]];
        if (size[to[i]] > size[bigs[u]])
            bigs[u] = to[i];
    }
}

void dfs2(int u, int Top)
{
    id[u] = ++cnt2;
    top[u] = Top;
    anc[u][0] = top[fa[top[u]]];
    deptop[u] = deptop[fa[top[u]] == root ? 0 : fa[top[u]]] + 1;
    for (int i = 1; i < 32; ++i)
        anc[u][i] = anc[fa[anc[u][i - 1]]][i - 1];
    if (!bigs[u])
        return;
    dfs2(bigs[u], Top);
    for (int i = head[u]; i; i = nxt[i])
    {
        if (!id[to[i]])
            dfs2(to[i], to[i]);
    }
}

int lca(int u, int v)
{
    if (top[u] == top[v])
        return dep[u] > dep[v] ? v : u;
    if (deptop[top[u]] < deptop[top[v]])
        std::swap(u, v);
    int x = top[u], y = top[v];
    for (int i = 29; i >= 0; --i)
        if (deptop[x] - (1 << i) > deptop[y])
            x = anc[x][i];
    if (top[fa[x]] == y)
        return dep[fa[x]] > dep[v] ? v : fa[x];
    if (deptop[x] ^ deptop[y])
        x = top[fa[x]];
    for (int i = 29; i >= 0; --i)
        if (anc[x][i] ^ anc[y][i])
            x = anc[x][i],
            y = anc[y][i];
    return dep[fa[x]] > dep[fa[y]] ? fa[y] : fa[x];
}

int x, y;

int main()
{
    scanf("%d%d%d", &n, &m, &root);
    for (int i = 1; i < n; ++i)
    {
        scanf("%d%d", &x, &y);
        add(x, y), add(y, x);
    }
    dfs1(root, root);
    dfs2(root, root);
    for (int i = 1; i <= m; ++i)
    {
        scanf("%d%d", &x, &y);
        printf("%d\n", lca(x, y));
    }
    return 0;
}

2023/10/11 01:03
加载中...