Cod sursa(job #2930015)

Utilizator andreiiorgulescuandrei iorgulescu andreiiorgulescu Data 27 octombrie 2022 12:29:53
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.76 kb
#include <bits/stdc++.h>

using namespace std;

ifstream in("lca.in");
ofstream out("lca.out");

int n,m,t[100005],fs[100005];
vector<int>f[100005];
int rmq[200005][20];
int euler[200005],s;
int lg[200005];
int height[200005];

void make_euler(int pos)
{
    euler[++s] = pos;
    for (int i = 0; i < f[pos].size(); i++)
    {
        height[f[pos][i]] = 1 + height[pos];
        make_euler(f[pos][i]);
        euler[++s] = pos;
    }
}

void make_rmq()
{
    for (int i = 1; i <= s; i++)
        rmq[i][0] = euler[i];
    for (int j = 1; j <= lg[s]; j++)
        for (int i = 1; i <= s - (1 << j) + 1; i++)
        {
            int h1 = height[rmq[i][j - 1]],h2 = height[rmq[i + (1 << (j - 1))][j - 1]];
            if (h1 > h2)
                rmq[i][j] = rmq[i + (1 << (j - 1))][j - 1];
            else
                rmq[i][j] = rmq[i][j - 1];
        }
}

int main()
{
    in >> n >> m;
    for (int i = 2; i <= n; i++)
        in >> t[i],f[t[i]].push_back(i);
    make_euler(1);
    for (int i = 2; i <= s; i++)
        lg[i] = 1 + lg[i / 2];
    for (int i = 1; i <= s; i++)
        if (fs[euler[i]] == 0)
            fs[euler[i]] = i;
    make_rmq();
    //for (int j = 0; j <= lg[s]; j++)
    //{
    //    for (int i = 1; i <= s - (1 << j) + 1; i++)
    //        cout << rmq[i][j] << ' ';
    //    cout << '\n';
    //}
    for (int i = 1; i <= m; i++)
    {
        int x,y;
        in >> x >> y;
        if (fs[x] > fs[y])
            swap(x,y);
        int a = fs[x],b = fs[y];
        int lgg = lg[b - a + 1];
        int p1 = rmq[a][lgg],p2 = rmq[b - (1 << lgg) + 1][lgg];
        if (height[p1] > height[p2])
            out << p2 << '\n';
        else
            out << p1 << '\n';
    }
    return 0;
}