Cod sursa(job #2788251)

Utilizator 100pCiornei Stefan 100p Data 25 octombrie 2021 13:32:34
Problema Lowest Common Ancestor Scor 0
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.65 kb
#include <bits/stdc++.h>
#define MAX 100000
#define TMAX 16
#define add emplace_back
#define mp make_pair
#define fastio std::ios_base::sync_with_stdio(NULL),cin.tie(NULL),cout.tie(NULL);
#define FILES freopen("lca.in","r",stdin);\
              freopen("lca.out","w",stdout);
using namespace std;
int n,q,a,lvl[MAX+5],nodes[MAX*2+5],ans[MAX*2+5][TMAX+1],poz[MAX+5],p2[TMAX+1],rm[MAX+5];
vector <int> v[MAX+5];
void dfs(int x,int level)
{
    nodes[0]++;
    nodes[nodes[0]] = x;
    poz[x] = nodes[0];
    lvl[x] = level;
    ans[nodes[0]][0] = x;
    for(auto i : v[x])
    {
        dfs(i,level+1);
        nodes[0]++;
        nodes[nodes[0]] = x;
        ans[nodes[0]][0] = x;
    }
}
int main()
{
    fastio
    FILES
    int x = 1,p = 1;
    while(x <= TMAX)
        p2[x] = p,x++,p *= 2;
    cin >> n >> q;
    for(int i = 2; i <= n; ++i)
    {
        cin >> a;
        v[a].add(i);
    }
    dfs(1,0);
    int t = nodes[0];
    for(int i = 1; i <= (int)(log2(nodes[0])); ++i)
    {
        t -= p2[i-1];
        for(int j = 1; j <= t; ++j)
        {
            if(lvl[ans[j][i-1]] > lvl[ans[j+p2[i-1]][i-1]])
                ans[j][i] = ans[j+p2[i-1]][i-1];
            else
                ans[j][i] = ans[j][i-1];
        }
    }
    int y;
    for(int i = 1; i <= q; ++i)
    {
        cin >> x >> y;
        x = poz[x],y = poz[y];
        if(x > y) swap(x,y);

        int lg = (y - x + 1),e = 0;
        p = 1;
        while(p * 2 <= lg) p *= 2,e++;
        if(lvl[ans[x][e]] > lvl[ans[y - p  + 1][e]])
            cout << ans[y-p+1][e] << '\n';
        else
            cout << ans[x][e] << '\n';
    }
}