Cod sursa(job #3131213)

Utilizator NiffSniffCojocaru Calin Marcu NiffSniff Data 19 mai 2023 15:51:27
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.86 kb
#include <fstream>
#include <vector>
using namespace std;
string file = "lca";
ifstream cin (file + ".in");
ofstream cout (file + ".out");
const int N = 100000;
vector <int> p, fii[N+1];
int dp[18][2*N+1],ne, nivel[N+1], prima_ap[N+1];
inline void putere()
{
    p.push_back(1);
    while (p.back() <= ne)
    {
        p.push_back(p.back() << 1);
    }
    p.pop_back();
}

inline void RMQ()
{
    int k = p.size();
    for (int i=1; i<k; i++)
    {
        for (int j=1; j<=p[i-1]; j++)
            dp[i][j] = dp[i-1][j];
        for (int j=p[i-1]+1; j<=ne; j++)
        {
            int st = dp[i-1][j-p[i-1]];
            int dr = dp[i-1][j];
            if (nivel[st] <= nivel[dr])
            {
                dp[i][j] = st;
            }
            else
            {
                dp[i][j] = dr;
            }
        }
    }
}

inline int cb (int x)
{
    int st = 0, dr = p.size()-1;
    while (st <= dr)
    {
        int mid = (st+dr)/2;
        if (p[mid] <= x)
        {
            st = mid+1;
        }
        else
        {
            dr = mid-1;
        }
    }
    return dr;
}

void dfs(int x)
{
    ++ne;
    dp[0][ne] = x;
    prima_ap[x] = ne;
    for (int y : fii[x])
    {
        nivel[y] = nivel[x] + 1;
        dfs(y);
        ne++;
        dp[0][ne] = x;
    }
}
int main ()
{
    int n,m,x,y;
    cin >> n >> m;
    for (int i=2; i<=n; i++)
    {
        cin >> x;
        fii[x].push_back(i);
    }
    dfs(1);
    putere();
    RMQ();
    for (int i=1; i<=m; i++)
    {
        cin >> x >> y;
        x = prima_ap[x];
        y = prima_ap[y];
        if (x > y)
            swap(x,y);
        int L = cb(y-x+1), st = dp[L][x+p[L]-1], dr = dp[L][y];
        if (nivel[st] <= nivel[dr])
            cout << st << '\n';
        else
            cout << dr << '\n';
    }
}