Cod sursa(job #3033103)

Utilizator pctirziuTirziu Petre pctirziu Data 23 martie 2023 13:06:14
Problema Lowest Common Ancestor Scor 0
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.72 kb
#include <fstream>
#include <vector>
#include <algorithm>

using namespace std;
ifstream cin("lca.in");
ofstream cout("lca.out");
const int nmax = 1e5 + 5;
int dp[18][nmax], depth[nmax], logaritm[nmax];
pair <long long, int> v[nmax];
vector <int> edge[nmax];
void dfs(int node, int parent)
{
    depth[node] = depth[parent] + 1;
    for(int i = 0; i < edge[node].size(); i++){
        int child = edge[node][i];
        if(child == parent)
            continue;
        dp[0][child] = node;
        for(int j = 1; j < 18; j++){
            if(dp[j - 1][dp[j - 1][child]] == 0)
                break;
            dp[j][child] = dp[j - 1][dp[j - 1][child]];
        }
        dfs(child, node);
    }
}
int lca(int x, int y)
{
    if(depth[x] < depth[y])
        swap(x, y);
    int k = depth[x] - depth[y];
    for(int i = logaritm[depth[x] - depth[y]]; i >= 0; i--)
        if(k & (1 << i))
            x = dp[i][x];
    if(x == y)
        return x;
    for(int i = logaritm[depth[x]]; i >= 0; i--)
        if(dp[i][x] != dp[i][y]){
            x = dp[i][x];
            y = dp[i][y];
        }
    return dp[0][x];
}
int main()
{
    int n, m;
    cin >> n >> m;
    for(int i = 2; i <= n; i++){
        int x;
        cin >> x;
        edge[x].push_back(i);
        edge[i].push_back(x);
    }
    depth[0] = -1;
    dfs(1, 0);
    while(m--){
        int x, y;
        cin >> x >> y;
        cout << lca(x, y) << "\n";
    }
    /*int t;
    cin >> t;
    for(int i = 0; i < 18; i++)
        if((1 << i) <= nmax)
            logaritm[(1 << i)] = 1;
    for(int i = 1; i <= nmax - 5; i++)
        logaritm[i] = logaritm[i - 1] + logaritm[i];
    while(t--){
        int n;
        cin >> n;
        for(int i = 1; i <= n; i++){
            cin >> v[i].first;
            v[i].second = i;
        }
        sort(v + 1, v + n + 1);
        for(int i = 1; i <= n - 1; i++){
            int x, y;
            cin >> x >> y;
            edge[x].push_back(y);
            edge[y].push_back(x);
        }
        depth[0] = -1;
        dfs(1, 0);
        bool ok = true;
        //v[0] = {1, 1};
        for(int i = 2; i <= n; i++){
            int lowest = lca(v[i].second, v[i - 1].second);
            int distanta = depth[v[i].second] + depth[v[i - 1].second] - 2 * depth[lowest];
            if(v[i].first - v[i - 1].first < distanta or (distanta & 1) != ((v[i].first - v[i - 1].first) & 1)){
                ok = false;
                break;
            }
        }
        cout << ok;
        for(int i = 1; i <= n; i++){
            for(int j = 0; j < 18; j++)
                dp[j][i] = 0;
            depth[i] = 0;
            edge[i].clear();
        }
    }*/
    return 0;
}