Cod sursa(job #3326988)

Utilizator zionlyismAdobroaiei David zionlyism Data 1 decembrie 2025 18:11:57
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.02 kb
#include <fstream>
#include <vector>

#define NMAX 100002
#define DIM 210000
using namespace std;

ifstream fin ("lca.in");
ofstream fout ("lca.out");

int n;
vector<vector<int>> graf;

int rmq[DIM][26], m; //m = nr querryuri

//pt LCA:
int Euler[DIM], nivel[DIM], first[NMAX];
int indic = 0; //nr de elemente din Euler

void citire();
void calcRMQ();
void DFS(int nod, int depth);

int main()
{
    citire();
    DFS(1, 0);
    calcRMQ();
    return 0;
}

void calcRMQ()
{
    int i, exp, power, u, v, l, r, lgsecv;
    //citire si precalculare pt lungime 1
    for(i = 1; i <= indic; i++) rmq[i][0] = i;
    //rmq
    for(power = 2, exp = 1; power <= indic; power *= 2, exp++) //power = puterea efectiva; j = exponentul pentru care se atinge puterea
        for(i = 1; i + power - 1 <= indic; i++)
            {
             u = rmq[i][exp - 1];
             v = rmq[i + power / 2][exp - 1];
             if (nivel[u] < nivel[v])
                rmq[i][exp] = u;
                else
                rmq[i][exp] = v;
            }
    //querry-urile
    for(i = 1; i <= m; i++)
    {
        fin>>u>>v;
        l = first[u];
        r = first[v];
        if(l > r) swap(l, r);
        lgsecv = r - l + 1;
        //calculeaza putere maxima care incape
        power = 1;
        exp = 0;
        while(power <= lgsecv)
        {
            power *= 2;
            exp++;
        }
        power /= 2;
        exp--;
        u = rmq[l][exp];
        v = rmq[r - power + 1][exp];
        if(nivel[u] < nivel[v])
           fout<<Euler[u]<<'\n';
           else
           fout<<Euler[v]<<'\n';
    }
}

void citire()
{
 int i, x;
 fin>>n>>m;
 graf.resize(n + 2);
 for(i = 2; i <= n; i++)
 {
    fin>>x;
    graf[x].push_back(i);
 }
}

void DFS(int nod, int depth)
{
 nivel[++indic]= depth;
 first[nod] = indic;
 Euler[indic] = nod;
 for(int i = 0; i < graf[nod].size(); i++)
 {
     DFS(graf[nod][i], depth + 1);
     nivel[++indic]= depth;
     Euler[indic] = nod;
 }
}