Cod sursa(job #1940504)

Utilizator jurjstyleJurj Andrei jurjstyle Data 26 martie 2017 17:24:39
Problema Lowest Common Ancestor Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2.06 kb
#include <fstream>
#include <vector>

using namespace std;

ifstream f("lca.in");
ofstream g("lca.out");

const int NMAX = 100002;

vector <int> G[NMAX];
int Euler_List[NMAX << 1], cnt_euler; //parcurgerea Euler a grafului
int Level[NMAX << 1]; //nivelul corespunzator nodului din parcurgerea lui Euler
int First_Poz[NMAX]; //memoreaza prima aparitie a nodului i
int Lg[NMAX << 1];
int RMQ[19][NMAX << 1]; //RMQ[i][j] - nodul de nivel minim corespunzator secventei [i, i + 2^j - 1] din reprezentarea lui Euler a arborelui
int N, M;


void DFS(int node, int level)
{
    First_Poz[node] = ++cnt_euler;
    Euler_List[cnt_euler] = node;
    Level[cnt_euler] = level;

    for (const int & x : G[node])
    {
        DFS(x, level + 1);
        Euler_List[++cnt_euler] = node;
        Level[cnt_euler] = level;
    }
}

void RMQ_process()
{
    for (int i = 1; i <= cnt_euler; ++i)
        RMQ[0][i] = i;
    for (int i = 1; (1 << i) < cnt_euler; ++i)
        for (int j = 1; j <= cnt_euler - (1 << (i - 1)); ++j)
            if (Level[RMQ[i - 1][j]] < Level[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))];
    for (int i = 2; i <= cnt_euler; ++i)
        Lg[i] = Lg[i >> 1] + 1;
}


int solve(int u, int v)
{
    //Lca(u, v) va fi nodul de nivel minim din secventa First[u], First[v]
    int a = First_Poz[u], b = First_Poz[v];
    if (a > b)  //avem nevoie de un interval "real"
        swap(a, b);
    int k = Lg[b - a + 1];
    if (Level[RMQ[k][a]] < Level[RMQ[k][b + (1 - (1 << k))]])
        return Euler_List[RMQ[k][a]];
    else
        return Euler_List[RMQ[k][b + (1 - (1 << k))]];
}

int main()
{
    f >> N >> M;
    for (int i = 2; i <= N; ++i)
    {
        int x;
        f >> x;
        G[x].push_back(i);
    }
    DFS(1, 0);
    RMQ_process();
    for (int i = 1; i <= M; ++i)
    {
        int u, v;
        f >> u >> v;
        g << solve(u, v) << "\n";
    }
    f.close();
    g.close();
    return 0;
}