Cod sursa(job #3200005)

Utilizator devilexeHosu George-Bogdan devilexe Data 3 februarie 2024 10:55:12
Problema Lowest Common Ancestor Scor 40
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.73 kb
#include <iostream>
#include <fstream>
#include <vector>

using namespace std;

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

#define limn 100010

int N, Q, k;
int dad[limn], depth[limn], poz[limn];
int rmq[20][limn], lg[limn];
// dad[i] = parintele lui i
// depth[i] = depth pt nodul i
vector<int> G[limn];

void euler(int node)
{
    rmq[0][++k] = node;
    poz[node] = k;
    depth[node] = depth[dad[node]] + 1;

    for (auto it : G[node])
    {
        euler(it);
        rmq[0][++k] = node;
    }
}

int main()
{
    int x, y;
    int pozX, pozY;

    fin >> N >> Q;
    for (int i = 2; i <= N; i++)
    {
        fin >> dad[i];
        G[dad[i]].push_back(i);
    }
    dad[1] = 1;
    depth[1] = 0; // depth in radacina e 0

    // path eulerian = dfs din 1
    euler(1);

    for(int i = 1; i <= k; ++i)
        cout << rmq[0][i] << ' ';
    cout << endl;

    // construim rmq
    for (int i = 1; (1 << i) <= k; i++)
        for (int j = 1; j + (1 << i) <=k+1; j++)
        {
            // calculam rmq[i][j]
            if (depth[rmq[i - 1][j]] < depth[rmq[i - 1][j + (1 << (i - 1))]])
                rmq[i][j] = rmq[i - 1][j];
            else
                rmq[i][j] = rmq[i - 1][j + (1 << (i - 1))];
        }

    // raspundem la query-uri

    while (Q--)
    {
        fin >> x >> y;
        x = poz[x];
        y = poz[y];
        if (x > y)
            swap(x, y);
        int diff = y-x+1;
        int lg = 0;
        while(diff >>= 1)
            lg++;
        cout << x << ' ' << y << ' ' << lg << endl;
        int level = lg;
        if (depth[rmq[level][x]] < depth[rmq[level][y - (1 << level) + 1]])
            fout << rmq[level][x] << '\n';
        else
            fout << rmq[level][y - (1 << level) + 1] << '\n';
    }

    return 0;
}