Cod sursa(job #3004027)

Utilizator gabriel.9619Gabriel Stefan Tita gabriel.9619 Data 16 martie 2023 08:56:19
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.8 kb
#include <fstream>
#define maxl 19
#define dim 100001
#include <vector>
using namespace std;
ifstream fin("lca.in");
ofstream fout("lca.out");

struct rmqI{
    int nod, niv;
}rmq[maxl][2*dim];

vector <int> l[dim];
int ps[2*dim], bit[2*dim], tata[dim];
int crt;

void dfs(int nod, int niv)
{
    crt++;
    rmq[0][crt]={nod, niv};
    ps[nod]=crt;
    for(int i=0;i<l[nod].size();i++)
    {
        dfs(l[nod][i], niv+1);
        crt++;
        rmq[0][crt]={nod, niv};
    }
}

void calcrmq()
{
    for(int p=1;p<maxl;p++)
    {
        for(int i=1;i<=crt;i++)
        {
            rmqI st, dr;
            st=rmq[p-1][i];
            if(i+(1<<(p-1))<=crt)
            {
                dr=rmq[p-1][i+(1<<(p-1))];
                if(st.niv<dr.niv)
                {
                    rmq[p][i]=st;
                }
                else
                {
                    rmq[p][i]=dr;
                }
            }
            else
            {
                rmq[p][i]=st;
            }
        }
    }
}

int lca(int x, int y)
{
    int posx=ps[x];
    int posy=ps[y];
    if(posx>posy)
    {
        swap(posx, posy);
    }
    int p=bit[posy-posx+1];
    rmqI st, dr;
    st=rmq[p][posx];
    dr=rmq[p][posy-(1<<p)+1];
    if(st.niv<dr.niv)
    {
        return st.nod;
    }
    else
    {
        return dr.nod;
    }
}

void calcbit()
{
    int i=1;
    bit[1]=0;
    for(i=2;i<=crt;i++)
    {
        bit[i]=1+bit[i/2];
    }
}

int main()
{
    int n, q, i, x, y;
    fin>>n>>q;
    for(i=2;i<=n;i++)
    {
        fin>>tata[i];
        l[tata[i]].push_back(i);
    }
    dfs(1, 0);
    calcbit();
    calcrmq();
    for(i=1;i<=q;i++)
    {
        fin>>x>>y;
        fout<<lca(x, y)<<"\n";
    }
    return 0;
}