Cod sursa(job #3257607)

Utilizator cris71Vlad Bogdan Cristian cris71 Data 18 noiembrie 2024 16:43:40
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.12 kb
#include <bits/stdc++.h>
using namespace std;
ifstream fin ("lca.in");
ofstream fout ("lca.out");
int const lmax=100007;
int const mmax=lmax*30;///nu merge pentru algoritmi unde memoria e mare
int euler[mmax],ind,n,q;
vector<int> G[lmax];
int rmq[27][mmax][2],lg2[mmax];
int level[lmax],firstap[lmax];
bool viz[lmax];///folosit pentru firstap
void precalc()
{
    for(int j=0;j<ind;j++)
    {
        rmq[0][j][0]=level[euler[j]];
        rmq[0][j][1]=euler[j];
    }
    for(int i=1;1<<i <= ind ; i++)
    {
        for(int j=0;j+(1<<i)-1<ind;j++)
        {
            //rmq[i][j]=min(rmq[i-1][j],rmq[i-1][j+(1<<(i-1))]);
            if(rmq[i-1][j][0]<=rmq[i-1][j+(1<<(i-1))][0])
            {
                rmq[i][j][0]=rmq[i-1][j][0];
                rmq[i][j][1]=rmq[i-1][j][1];
            }
            else
            {
                rmq[i][j][0]=rmq[i-1][j+(1<<(i-1))][0];
                rmq[i][j][1]=rmq[i-1][j+(1<<(i-1))][1];
            }
        }
    }
}
void dfs(int node, int dad)
{
    euler[ind++]=node;
    level[node]=level[dad]+1;
    for(auto vec:G[node])
    {
        if(vec==dad)continue;
        dfs(vec,node);
        euler[ind++]=node;
    }
}
int querry(int a, int b)
{
    a=firstap[a];
    b=firstap[b];
    if(a>b)
    {
        swap(a,b);///a va fi mereu "st" si b "dr"
    }
    int len=b-a+1;
    int loglen=lg2[len];
    return min(rmq[loglen][a][1],rmq[loglen][b+1-(1<<loglen)][1]);///trebuie sa fac legatura intre minim si nodul care ii apartine
}
int main()
{
    fin>>n>>q;
    for(int i=2;i<n+1;i++)
    {
        int a;
        fin>>a;
        G[a].push_back(i);
        G[i].push_back(a);
    }
    level[1]=1;
    dfs(1,0);
    for(int i=2;i<=ind;i++)
    {
        lg2[i]=lg2[i>>1]+1;
    }
    for(int i=0;i<ind;i++)
    {
        if(viz[euler[i]]==false)
        {
            viz[euler[i]]=true;
            firstap[euler[i]]=i;
        }
    }
    precalc();
    for(int i=0;i<q;i++)
    {
        int a, b;
        fin>>a>>b;
        fout<<querry(a,b)<<"\n";
    }
    fin.close();
    fout.close();
    return 0;
}