Mai intai trebuie sa te autentifici.

Cod sursa(job #2477633)

Utilizator rd211Dinucu David rd211 Data 20 octombrie 2019 20:20:07
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.08 kb
#include <bits/stdc++.h>

using namespace std;
const int NMAX = 100010;
int n,m;
ifstream fin("lca.in");
ofstream fout("lca.out");
vector<int> graf[NMAX];
vector<pair<int,int>> eulerPath;
int firstAppear[NMAX];

void dfs(int node,int father,int depth)
{
    if(firstAppear[node]==-1)
        firstAppear[node]=eulerPath.size();
    eulerPath.push_back({node,depth});
    for(int i = 0; i<graf[node].size(); i++)
    {
        if(graf[node][i] != father)
        {
            dfs(graf[node][i],node,depth+1);
            eulerPath.push_back({node,depth});
        }
    }
}

int main()
{
    fin>>n>>m;
    int x,y;
    for(int i = 1; i<n; i++)
    {
        fin>>x;
        graf[x].push_back(i+1);
    }
    fill(firstAppear,firstAppear+NMAX,-1);
    dfs(1,-1,0);


    vector<int> log_table(eulerPath.size()+10,0);
    for(int i = 2; i<log_table.size(); i++)
    {
        log_table[i]=log_table[i/2]+1;
    }

    vector<vector<pair<int,int>>> sparse_table(log_table.back()+1,vector<pair<int,int>>(eulerPath.size()));
    sparse_table[0]=eulerPath;
    for(int i = 1; i<sparse_table.size(); i++)
    {
        for(int j = 0; j+(1<<i)<=eulerPath.size(); j++)
        {
            pair<int,int> leftComp = sparse_table[i-1][j],rightComp=sparse_table[i-1][j+(1<<(i-1))];
            if(leftComp.second>rightComp.second)
            {
                sparse_table[i][j]=rightComp;
            }
            else
            {
                sparse_table[i][j]=leftComp;
            }
        }
    }
    while(m--)
    {
        fin>>x>>y;
        if(x==y)
        {
            fout<<x<<'\n';
        }
        else
        {
            int l=min(firstAppear[x],firstAppear[y]),r=max(firstAppear[x],firstAppear[y]);
            int log = log_table[r-l];
            pair<int,int> leftComp = sparse_table[log][l],rightComp=sparse_table[log][r-(1<<log)];
            if(leftComp.second>rightComp.second)
                fout<<rightComp.first<<'\n';
            else
                fout<<leftComp.first<<'\n';
        }
    }

    return 0;
}