社区讨论

卡常求助

P3379【模板】最近公共祖先(LCA)参与者 12已保存回复 20

讨论操作

快速查看讨论及其快照的属性,并进行相关操作。

当前回复
20 条
当前快照
1 份
快照标识符
@mi7xv8j6
此快照首次捕获于
2025/11/21 05:24
4 个月前
此快照最后确认于
2025/11/21 06:40
4 个月前
查看原帖
T * 3, 用了氧气优化可以AC,关闭同步输入输出T * 2,想知道怎么优化常数。。
附上代码
CPP
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;

const int maxn = 500000 + 10;
int fa[maxn][25], h[maxn], lg[maxn];
vector <int> G[maxn];

void dfs(int u, int fath)
{
    fa[u][0] = fath;
    if (fath == -1)   h[u] = 1;
    else    h[u] = h[fath] + 1;
    for (int i = 1; (1 << i) <= h[u]; i++)
    {
        fa[u][i] = fa[fa[u][i - 1]][i - 1];
    }
    int tn = G[u].size();
    for (int i = 0; i < tn; i++)
    {
        int v = G[u][i];
        if (v != fath)
        {
            fa[v][0] = u;
            dfs(v, u);
        }
    }
}

int lca(int a, int b)
{
    if (h[a] < h[b])    swap(a, b);
    while(h[a] > h[b])
    {
        a = fa[a][lg[h[a] - h[b]] - 1];
    }
    if (a == b)
    {
        return a;
    }
    for (int i = lg[h[a] - 1]; i >= 0; i--)
    {
        if (fa[a][i] != fa[b][i])
        {
            a = fa[a][i];
            b = fa[b][i];
        }
    }
    return fa[a][0];
}

int main()
{

    ios::sync_with_stdio(false); cin.tie(0);
    int n = 0, m = 0, s = 0;    cin >> n >> m >> s;
    for (int i = 1; i <= n - 1; i++)
    {
        int a = 0, b = 0;   cin >> a >> b;
        G[a].push_back(b);
        G[b].push_back(a);
    }
    dfs(s, -1);
    /* for (int i = 1; i <= n; i++)
    {
        printf("x = %d, h = %d\n", i, h[i]);
    } */
    for (int i = 1; i <= n; i++)
    {
        lg[i] = lg[i - 1] + (1 << lg[i - 1] == i);
    }
    for (int i = 1; i <= m; i++)
    {
        int a = 0, b = 0;   cin >> a >> b;
        cout << lca(a, b) << '\n';
    }
    getchar(); getchar();
    return 0;
}

回复

20 条回复,欢迎继续交流。

正在加载回复...