Cod sursa(job #2957591)

Utilizator AswVwsACamburu Luca AswVwsA Data 22 decembrie 2022 22:20:39
Problema Lowest Common Ancestor Scor 0
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.25 kb
#include <fstream>
#include <cstring>
#include <climits>
#include <algorithm>
#include <vector>
#include <signal.h>
#define ll long long
using namespace std;

const int NMAX = 100000;
const int LGMAX = 17;
vector <int> g[NMAX + 1];

int aib[2 * NMAX + 1];
int st[NMAX + 1], dr[NMAX + 1];
int d[NMAX + 1];
int lg[NMAX + 1];

int dp[NMAX + 1][LGMAX + 1];
bool viz[NMAX + 1];
int dim;
void update(int poz, int val)
{
    while (poz <= dim)
    {
        aib[poz] += val;
        poz += poz & -poz;
    }
}

int query(int val)
{
    int ans = 0;
    while (val)
    {
        ans += aib[val];
        val -= val & -val;
    }
    return ans;
}
int aux;
void dfs(int nod)
{
    viz[nod] = 1;
    ++aux;
    st[nod] = aux;
    update(aux, 0);
    for (int u : g[nod])
        if (!viz[u])
        {
            dp[u][0] = nod;
            d[u] = d[nod] + 1;
            dfs(u);
        }
    ++aux;
    update(aux, 0);
    dr[nod] = aux;
}

void removeEdge(int a, int b)
{
    if (d[a] < d[b])
        swap(a, b);
    update(st[a], 1);
    update(dr[a], -1);
}
int lca(int a, int b)
{
    if (d[a] < d[b])
        swap(a, b);
    int i, need = d[a] - d[b];
    for (i = 0; (1 << i) <= need; i++)
        if (need & (1 << i))
            a = dp[a][i];

    if (a == b)
        return a;
    int ans = 0;
    for (i = lg[d[a]]; i >= 0; i--)
        if (dp[a][i] == dp[b][i])
        {
            ans = dp[a][i];
        }
        else
        {
            a = dp[a][i];
            b = dp[b][i];
        }
    return ans;
}

int dist(int a, int b)
{
    return query(st[a]) + query(st[b]) - 2 * query(st[lca(a, b)]);
}
int main()
{
    ifstream cin("disconnect.in");
    ofstream cout("disconnect.out");
    int n, m, i, j;
    cin >> n >> m;
    int v = 0;
    dim = 2 * n;
    for (i = 2; i <= n; i++)
    {
        int x;
        cin >> x;
        dp[i][0] = x;
        g[x].push_back(i);
        g[i].push_back(x);
        lg[i] = lg[i / 2] + 1;
    }
    for (j = 1; j <= lg[n]; j++)
        for (i = 1; i <= n; i++)
            dp[i][j] = dp[dp[i][j - 1]][j - 1];
    dfs(1);
    while (m--)
    {
        int a, b;
        cin >> a >> b;
        cout << lca(a, b) << "\n";
    }
}