Cod sursa(job #3168513)

Utilizator unomMirel Costel unom Data 12 noiembrie 2023 17:02:24
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.43 kb
#include <fstream>
#include <vector>
#include <cmath>

using namespace std;

ifstream in("lca.in");
ofstream out("lca.out");
int n, m, q;
vector<int> v[100005];
pair<int, int> euler[200005];
int nr;
int viz[100005];
int t[200005][25];
int first[100005];

void dfs(int nod, int nivel)
{
    viz[nod] = 1;
    nr++;
    euler[nr] = {nod, nivel};

    for(auto j: v[nod])
    {
        if(viz[j] == 0)
        {
            dfs(j, nivel + 1);

            nr++;
            euler[nr] = {nod, nivel};
        }
    }
}

int main()
{
    in>>n>>q;

    int w;
    for(int i = 2; i<=n; i++)
    {
        in>>w;
        v[w].push_back(i);
    }


    dfs(1, 0);

    /*for(int i = 1; i<=nr; i++)
    {
        out<<euler[i].first<<" ";
    }
    out<<'\n';
    for(int i = 1; i<=nr; i++)
    {
        out<<euler[i].second<<" ";
    }
    out<<'\n';*/

    for(int i = 1; i<=nr; i++)
    {
        if(first[euler[i].first] == 0)
        {
            first[euler[i].first] = i;
        }
    }

    /*for(int i = 1; i<=n; i++)
    {
        out<<first[i]<<" ";
    }
    out<<'\n';*/

    int put = 1;
    int m = log2(nr) + 1;

    for(int j = 1; j<=m; j++)
    {
        if(j == 1)
        {
            for(int i = 1; i<=nr-put+1; i++)
            {
                t[i][j] = i;
            }
        }
        else
        {
            for(int i = 1; i<=nr-put+1; i++)
            {
                if(euler[t[i][j-1]].second < euler[t[i+(put/2)][j-1]].second)
                {
                    t[i][j] = t[i][j-1];
                }
                else
                {
                    t[i][j] = t[i+(put/2)][j-1];
                }
            }
        }
        put *= 2;
    }

    int nod1, nod2;
    int x, y, k, l, p;
    int m1, m2;
    while(q--)
    {
        in>>nod1>>nod2;

        x = first[nod1];
        y = first[nod2];

        if(x > y)
        {
            swap(x, y);
        }

        //out<<x<<" "<<y<<" -> ";

        l = y - x + 1;
        k = (int)log2(l);

        m1 = t[x][k+1];

        p = l - pow(2, k);

        m2 = t[x+p][k+1];

        //out<<euler[m1].second <<" "<< euler[m2].second<<" -> ";

        if(euler[m1].second <= euler[m2].second)
        {
            out<<euler[m1].first<<'\n';
        }
        else
        {
            out<<euler[m2].first<<'\n';
        }
    }

    return 0;
}