Cod sursa(job #1537905)

Utilizator sabauandrei98Sabau Andrei sabauandrei98 Data 28 noiembrie 2015 11:45:57
Problema Lowest Common Ancestor Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.69 kb
#include <iostream>
#include <vector>
#include <fstream>

using namespace std;

#define nmax 100005

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

int euler[2*nmax],
    lev[nmax],
    first[nmax],
    log[2*nmax],
    rmq[18][2*nmax],
    nod[18][2*nmax];

vector<int> v[nmax];
int n,m,cnt = 0;

void DFS(int x)
{
    euler[++cnt] = x;
    first[x] = cnt;

    for(int i = 0; i < v[x].size(); i++)
    {
        int nod = v[x][i];

        lev[nod] = lev[x] + 1;
        DFS(nod);
        euler[++cnt] = x;
    }
}

int lca(int x, int y)
{
    x = first[x];
    y = first[y];

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

    int dif = y - x + 1;
    int p = log[dif];

    if (rmq[p][x] < rmq[p][y - (1<<p) + 1])
        return nod[p][x];

    return nod[p][y - (1<<p) + 1];
}

void RMQ()
{
    for(int i = 1; i<=cnt; i++)
    {
        rmq[0][i] = lev[euler[i]];
        nod[0][i] = euler[i];
    }

    for(int i = 1;  (1<<i) <= cnt; i++)
        for(int j = 1; j + (1<<i) - 1 <= cnt; j++)
        if (rmq[i-1][j] < rmq[i-1][j+ (1<<(i-1))])
        {
            rmq[i][j] = rmq[i-1][j];
            nod[i][j] = nod[i-1][j];
        }
        else
        {
            rmq[i][j] = rmq[i-1][j + (1<<i-1)];
            nod[i][j] = nod[i-1][j + (1<<i-1)];
        }
}

int main()
{
    f >> n >> m;

    for(int i = 1; i <= n - 1; i++)
    {
        int tata;
        f >> tata;
        v[tata].push_back(i+1);
    }

    DFS(1);

    for(int i = 2; i<=cnt ; i++)
        log[i] = log[i/2] + 1;

    RMQ();

    int x,y;
    for(int i = 1; i<=m; i++)
    {
        f >> x >> y;
        g << lca(x,y) << '\n';
    }

    return 0;
}