Cod sursa(job #3360567)

Utilizator florinul1Iuhas Florin florinul1 Data 14 iulie 2026 16:37:20
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 3.21 kb
/**
//met I, cu AIB
#include <iostream>
#include <fstream>
#include <vector>
#include <bitset>

using namespace std;

const int N=1e5+5,M=18;
int n,m,pc;
int t[N];
int p_start[N],p_end[N];
int stramos[N][M];
bitset<N> viz;
vector<int> g[N];

bool este_stramos(int x,int y)
{
    return p_start[x]<=p_start[y] and p_end[y]<=p_end[x];
}

void dfs(int nod)
{
    viz[nod]=1;
    p_start[nod]=pc++;
    for(auto el:g[nod])
        if(!viz[el])
            dfs(el);
    p_end[nod]=pc++;
}

int lca(int a, int b)
{
    if(este_stramos(a,b))return a;
    if(este_stramos(b,a))return b;
    for(int p=M-1; p>=0; p--)
    {
        int c=stramos[a][p];
        if(c and !este_stramos(c,b))
        {
            a=c;
        }
    }
    return stramos[a][0];
}

void generare_stramosi()
{
    int i(1);
    for(; i<=n; i++)stramos[i][0]=t[i];
    for(int p(1); p<M; p++)
    {
        for(int nod=1; nod<=n; nod++)
            stramos[nod][p]=
                stramos[stramos[nod][p-1]][p-1];
    }
}

int main()
{
    ifstream fin("lca.in");
    fin>>n>>m;
    int i(2),j;
    for(; i<=n; i++)
    {
        fin>>t[i];
        g[t[i]].push_back(i);
    }
    dfs(1);
    generare_stramosi();
    ofstream fout("lca.out");
    while(m--)
    {
        fin>>i>>j;
        fout<<lca(i,j)<<'\n';
    }
    fin.close();
    fout.close();
    return 0;
}
*/

#include <iostream>
#include <fstream>
#include <vector>
#include <bitset>
#include <iomanip>

using namespace std;

struct Lucriri_pt_RMQ
{
    int nod,niv;
};

const int N=1e5+5,M=18;
int n,m,cnt;
int t[N];
int p_start[2*N],logaritm[2*N];
Lucriri_pt_RMQ rmq[N*2][M];
bitset<N> viz;
vector<int> g[N];

void dfs(int nod,int niv)
{
    viz[nod]=1;
    p_start[nod]=++cnt;
    rmq[cnt][0]= {nod,niv};
    for(auto el:g[nod])
        if(!viz[el])
        {
            dfs(el,niv+1);
            rmq[++cnt][0]= {nod,niv};
        }
}

int lca(int a, int b)
{
    int pa=p_start[a],pb=p_start[b];
    if(pa>pb)swap(pa,pb);
    if(rmq[pa][logaritm[pb-pa+1]].niv<
            rmq[pb-(1<<(logaritm[pb-pa+1]))+1][(logaritm[pb-pa+1])].niv)
        return rmq[pa][(logaritm[pb-pa+1])].nod;
    return rmq[pb-(1<<(logaritm[pb-pa+1]))+1][(logaritm[pb-pa+1])].nod;
}

void generare_rmq()
{
    for(int p(1); p<M; p++)
    {
        for(int nod=1; nod<=cnt; nod++)
        {
            rmq[nod][p]=rmq[nod][p-1];
            if(nod+(1<<(p-1))<=cnt&&
                    rmq[nod][p].niv>rmq[nod+(1<<(p-1))][p-1].niv)
                rmq[nod][p]=rmq[nod+(1<<(p-1))][p-1];
        }
    }
}

void generare_logaritmi()
{
    for(int i(2); i<=cnt; ++i)logaritm[i]=1+logaritm[i/2];
}

int main()
{
    ifstream fin("lca.in");
    fin>>n>>m;
    int i(2),j;
    for(; i<=n; i++)
    {
        fin>>t[i];
        g[t[i]].push_back(i);
    }
    dfs(1,1);
    generare_rmq();
    generare_logaritmi();
    ofstream fout("lca.out");
    while(m--)
    {
        fin>>i>>j;
        fout<<lca(i,j)<<'\n';
    }
    fin.close();
    fout.close();
    for(j=0; j<M; j++,cout<<'\n')
        for(i=1; i<=cnt; i++)
        {
            cout<<setw(3)<<rmq[i][j].niv<<' ';
        }
    return 0;
}