Cod sursa(job #1083010)

Utilizator PsychoAlexAlexandru Buicescu PsychoAlex Data 15 ianuarie 2014 15:03:47
Problema Lowest Common Ancestor Scor 30
Compilator cpp Status done
Runda Arhiva educationala Marime 2.47 kb
#include <iostream>
#include <fstream>
#include <vector>
#include <unordered_map>
#include <stdlib.h>

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

int n, m;
int rmq[18][100001][2];
int lg[100001];

void min(int a[2], int b[2], int &minim, int &resp)
{
    if(a[1] > b[1])
    {
        minim = b[1];
        resp = b[0];
    }
    else
    {
        minim = a[1];
        resp = a[0];
    }
}

int visited[10000001];
int visited2[10000001][2];
std::vector<int> noduri[100001];
int euler[100001];
std::unordered_map<int, std::vector<int> > hashu;

void dfs(int nod, int adancime, int &r)
{
    visited[nod] = adancime;
    visited2[r][0] = nod;
    visited2[r][1] = adancime;
    hashu[nod].push_back(r);

    for(int i = 0; i < noduri[nod].size(); i++)
    {
        if(!visited[noduri[nod][i]])
        {
            r++;
            dfs(noduri[nod][i], adancime + 1, r);
            r++;
            visited2[r][0] = nod;
            visited2[r][1] = adancime;
            hashu[nod].push_back(r);
        }
    }
}

void citire()
{
    int p;
    fin>>n>>m;
    for(int i = 2; i <= n; i++)
    {
        fin>>p;
        noduri[p].push_back(i);
    }

    int sis = 0;
    dfs(1, 0, sis);

    for(int i = 0; i <= sis; i++)
    {
        rmq[0][i][0] = visited2[i][0];
        rmq[0][i][1] = visited2[i][1];
    }

    for(int i = 1; (1<<i) <= n; i++)
    {
        for(int j = 0; j < sis - (1<<i) + 1; j++)
        {
            int leng = (1<<(i-1));
            min(rmq[i-1][j], rmq[i-1][j+leng], rmq[i][j][1], rmq[i][j][0]);
        }
    }

    for(int i = 2; i <= sis; i++)
    {
        lg[i] = lg[i / 2] + 1;
    }

    int x, y;
    for(int i = 0; i < m; i++)
    {
        fin>>x>>y;

        int psst1, psst2;

        if(hashu[x].front() > hashu[y].front())
        {
            psst1 = hashu[x].front();
            psst2 = hashu[y].front();
        }
        else
        {
            psst2 = hashu[x].front();
            psst1 = hashu[y].front();
        }

        int lung = psst1 - psst2 + 1;
        int val1, val2;

        min(rmq[lg[lung]][psst2], rmq[lg[lung]][psst2 + lung - (1<<lg[lung])], val1, val2);
        if(val2 == 0)
        {
            //std::cout<<1<<'\n';
            fout<<1<<'\n';
        }
        else
        {
//            std::cout<<val2<<'\n';
            fout<<val2<<'\n';
        }
    }
}

int main()
{
    citire();
    return 0;
}