Cod sursa(job #2919145)

Utilizator BlueLuca888Girbovan Robert Luca BlueLuca888 Data 15 august 2022 22:41:45
Problema Lowest Common Ancestor Scor 90
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.52 kb
#include <bits/stdc++.h>
#pragma GCC optimize ("Ofast")

using namespace std;

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

const int MAX_N = 100005;
int n, q, x, sx, y, sy;
int ancestor[17][MAX_N], level[MAX_N];
vector <int> leaves[MAX_N];

inline void set_levels(int nod, int lvl){
    level[nod] = lvl;
    for(auto leaf : leaves[nod])
        set_levels(leaf, lvl+1);
}

int pw2;
static inline int stramos(int nod, int dist){
    pw2 = 0;
    while(dist){
        if(dist & 1)
            nod = ancestor[pw2][nod];
        pw2++;
        dist >>= 1;
    }
    return nod;
}

int main (){
    ios_base::sync_with_stdio(false);
    fin.tie(nullptr), fout.tie(nullptr);

    fin>>n>>q;
    for(int j=2; j<=n; j++){
        fin>>ancestor[0][j];
        leaves[ ancestor[0][j] ].push_back(j);
    }

    set_levels(1, 1);

    for(int i=1; (1 << i)<=n; i++)
        for(int j=1; j<=n; j++)
            ancestor[i][j] = ancestor[i-1][ ancestor[i-1][j] ];

    int st, md, dr, sol;
    while(q--){
        fin>>x>>y;

        if(level[x] < level[y])
            swap(x, y);

        x = stramos(x, level[x] - level[y]);

        st = 0;
        dr = level[x]-1;
        while(st <= dr){
            md = st + ((dr - st) >> 1);
            sx = stramos(x, md);
            sy = stramos(y, md);

            if(sx == sy){
                sol = sx;
                dr = md - 1;
            }else
                st = md + 1;
        }
        fout<<sol<<"\n";
    }
    return 0;
}