Cod sursa(job #3235431)

Utilizator rapidu36Victor Manz rapidu36 Data 17 iunie 2024 20:39:57
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.74 kb
#include <fstream>
#include <vector>

using namespace std;

const int N = 1e5;
const int L = 17;

int t[N+1], rmq[L+1][2*N+1], poz[N+1], nivel[N+1], log_2[2*N+1];
vector <int> fii[N+1];
vector <int> e;

void parcurgere_euler(int x)
{
    e.push_back(x);
    poz[x] = (int)e.size() - 1;
    if (x == 1)
    {
        nivel[x] = 0;
    }
    else
    {
        nivel[x] = 1 + nivel[t[x]];
    }
    for (auto y: fii[x])
    {
        parcurgere_euler(y);
        e.push_back(x);
    }
}

int main()
{
    ifstream in("lca.in");
    ofstream out("lca.out");
    int n, q;
    in >> n >> q;
    for (int i = 2; i <= n; i++)
    {
        in >> t[i];
        fii[t[i]].push_back(i);
    }
    parcurgere_euler(1);
    for (int j = 0; j < (int)e.size(); j++)
    {
        rmq[0][j] = e[j];
    }
    for (int i = 1; (1 << i) <= (int)e.size(); i++)
    {
        for (int j = (1 << i) - 1; j < (int)e.size(); j++)
        {
            int  p = 1 << (i - 1);
            rmq[i][j] = rmq[i-1][j-p];
            if (nivel[rmq[i-1][j]] < nivel[rmq[i][j]])
            {
                rmq[i][j] = rmq[i-1][j];
            }
        }
    }
    log_2[1] = 0;
    for (int i = 2; i <= (int)e.size(); i++)
    {
        log_2[i] = 1 + log_2[i/2];
    }
    for (int i = 0; i < q; i++)
    {
        int x, y;
        in >> x >> y;
        int st = poz[x], dr = poz[y];
        if (st > dr)
        {
            swap(st, dr);
        }
        int ex = log_2[dr-st+1];
        int p = 1 << ex;
        int rez = rmq[ex][st+p-1];
        if (nivel[rmq[ex][dr]] < nivel[rez])
        {
            rez = rmq[ex][dr];
        }
        out << rez << "\n";
    }
    in.close();
    out.close();
    return 0;
}