Cod sursa(job #791348)

Utilizator repp4raduRadu-Andrei Szasz repp4radu Data 23 septembrie 2012 20:57:13
Problema Lowest Common Ancestor Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.53 kb
#include <fstream>
#include <vector>

#define MAX 131072

using namespace std;

vector<int> v[MAX], f, euler, lvl;
int lg2[MAX << 1], rmq[20][MAX << 2], n, a, b, m;

void Logarithm()
{
    lg2[1] = 0;
    for(int i = 2; i <= 2 * n; i++) lg2[i] = lg2[i >> 1] + 1;
}

void dfs(int nod, int level)
{
    euler.push_back(nod); lvl.push_back(level);
    if(f[nod] == -1) f[nod] = euler.size() - 1;
    for(int i = 0; i < v[nod].size(); i++)
    {
        dfs(v[nod][i], level + 1);
        euler.push_back(nod); lvl.push_back(level);
    }
}

void RMQ()
{
    for(int i = 0; i < euler.size(); i++)
        rmq[0][i] = i;
    for(int i = 1; (1 << i) < euler.size(); i++)
        for(int j = 0; j < euler.size() - (1 << i); j++)
        {
            rmq[i][j] = rmq[i - 1][j + (1 << (i - 1))];
            if(lvl[rmq[i - 1][j]] < lvl[rmq[i][j]])
                rmq[i][j] = rmq[i - 1][j];
        }
}

int main()
{
    ifstream in("lca.in"); in>>n>>m;
    for(int i = 2; i <= n; i++)
    {
        in>>a;
        v[a].push_back(i);
    }
    f.assign(n + 1, -1);
    Logarithm();
    dfs(1, 0);
    RMQ();
    ofstream out("lca.out");
    for(int i = 1; i <= m; i++)
    {
        in>>a>>b;
        a = f[a]; b = f[b];
        if(a > b) swap(a, b);
        int lg = lg2[b - a + 1];
        if(lvl[rmq[lg][a]] < lvl[rmq[lg][b - (1 << lg) + 1]])
            out<<euler[rmq[lg][a]]<<"\n";
        else
            out<<euler[rmq[lg][b - (1 << lg) + 1]]<<"\n";
    }
    out.close(); in.close();
    return 0;
}