Cod sursa(job #3038895)

Utilizator RTG123Razvan Diaconescu RTG123 Data 27 martie 2023 21:36:45
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.08 kb
#include <iostream>
#include <fstream>
#include <vector>
#include <stack>
#define INF 10000000000
#define MAX_N 100001
#define nst (nod <<1)
#define ndr (nst | 1)
#define mij ((li+ls)>>1)
using namespace std;
ifstream f("lca.in");
ofstream g("lca.out");
int n,m,dads[MAX_N],viz[MAX_N],adi[MAX_N<<4],l[MAX_N<<1],sol,hsol,first[MAX_N];
vector <int> rep_euler;
vector <vector <int>> v(MAX_N);
void make_euler ()
{
    stack<pair<int,int>> st;
    st.push(make_pair(1,0));
  //  rep_euler.push_back(1);
    while (!st.empty())
    {
        int cur=st.top().first,ok=0;
        rep_euler.push_back(cur);
        l[rep_euler.size()-1]=st.top().second;
        first[cur]=rep_euler.size()-1;
        viz[cur]=1;
        for (int i=0; i<v[cur].size() && !ok; i++)
        {
            int next=v[cur][i];
            if (!viz[next])
            {
                ok=1;
                viz[next]=1;
                st.push(make_pair(next,st.top().second+1));
            }
        }
        if (!ok)
        {
            st.pop();
        }
    }
}
void build (int nod,int li,int ls)
{
    if (li==ls)
    {
        adi[nod]=li;
        return ;
    }
    build(nst,li,mij);
    build(ndr,mij+1,ls);
    if (l[adi[nst]]<=l[adi[ndr]])
        adi[nod]=adi[nst];
    else adi[nod]=adi[ndr];
}
void query(int nod,int st,int dr,int li,int ls)
{
    if (st<=li && ls<=dr)
    {
        if (l[adi[nod]]<hsol)
            sol=rep_euler[adi[nod]],hsol=l[adi[nod]];
            return ;
    }
    if (st<=mij)
        query(nst,st,dr,li,mij);
    if (mij<dr)
        query(ndr,st,dr,mij+1,ls);
}
int lca (int a,int b)
{
    int st=first[a],dr=first[b];
    if (st>dr)
        swap(st,dr);
    sol=hsol=INF;
    query (1,st,dr,1,rep_euler.size());
    return sol;
}
int main()
{
    f>>n>>m;
    for (int i=2; i<=n; i++)
    {
        f>>dads[i];
        v[dads[i]].push_back(i);
    }
    make_euler();
    build(1,1,rep_euler.size());
    for (int i=1; i<=m; i++)
    {
        int x,y;
        f>>x>>y;
        g<<lca(x,y)<<'\n';
    }
    return 0;
}