Cod sursa(job #2466729)

Utilizator Cezar211Popoveniuc Cezar Cezar211 Data 2 octombrie 2019 20:41:45
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.96 kb
#include <bits/stdc++.h>
#define NM 100100
using namespace std;
ifstream fin ("lca.in");
ofstream fout ("lca.out");
void read();
void dfs(int x);
void det_level(int x);
void build_rmq();
int rmq_val(int x, int y);
int n, q, x, y, node, minn, t[NM], ap[NM], nr_ap, niv_cur;
vector<int> v[NM];
vector<pair<int,int>> rmq[20];///minim, node with minimum level
vector<int> e, niv;///Euler traversal, level of node in e
int main()
{
    read();
    build_rmq();
    for(int i=1; i<=q; i++)
    {
        fin >> x >> y;
        fout << rmq_val(ap[x], ap[y]) << '\n';
    }
    return 0;
}
int rmq_val(int x, int y)///call for ap[x/y]
{
    if(x > y)
        swap(x, y);
    int p = log2(y-x+1);
    if(rmq[p][x].first < rmq[p][y-(1<<p)+1].first)
        return rmq[p][x].second;
    else return rmq[p][y-(1<<p)+1].second;
}
void build_rmq()
{
    int N = niv.size();
    rmq[0].push_back({0, 0});
    for(int i=0; i<N; i++)
        rmq[0].push_back(pair<int,int>(niv[i], e[i]));
    for(int i=1; (1<<i)<=N; i++)
    {
        rmq[i].push_back({0, 0});
        for(int j=1; j<=N-(1<<i)+1; ++j)
        {
            if(rmq[i-1][j].first < rmq[i-1][j+(1<<(i-1))].first)
                node = rmq[i-1][j].second;
            else node = rmq[i-1][j+(1<<(i-1))].second;
            int minn = min(rmq[i-1][j].first, rmq[i-1][j+(1<<(i-1))].first);
            rmq[i].push_back(pair<int,int>(minn, node));
        }
    }
}
void read()
{
    fin >> n >> q;
    for(int i=2; i<=n; i++)
        fin >> t[i];
    ///build adjacency matrix
    for(int i=2; i<=n; i++)
        v[t[i]].push_back(i);

    ///Euler traversal and
    ///level determination and
    ///first appearance
    dfs(1);
}
void dfs(int x)
{
    niv_cur++;
    e.push_back(x);
    niv.push_back(niv_cur);
    if(ap[x] == 0)
        ap[x] = e.size();
    for(auto it:v[x])
    {
        dfs(it);
        e.push_back(x);
        niv.push_back(niv_cur);
    }
    niv_cur--;
}