Cod sursa(job #1051728)

Utilizator PsychoAlexAlexandru Buicescu PsychoAlex Data 10 decembrie 2013 15:21:31
Problema Lowest Common Ancestor Scor 0
Compilator cpp Status done
Runda Arhiva educationala Marime 4.56 kb
#include <iostream>
#include <fstream>
#include <vector>
#include <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];
//int vec[100001][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::map<int, std::vector<int> > hashu;

void dfs(int nod, int adancime, int &r)
{
//    std::cout<<nod<<' ';
    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);

//        for(int j = 0; j < n; j++)
//        {
//            fin>>vec[i][j];
//            rmq[0][i][j] = vec[i][j];
//        }
    }

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

//    for(int i = 1; i <= n; i++)
//    {
//        std::cout<<i<<' '<<visited[i]<<'\n';
//    }
//    for(int i = 0; i <= sis; i++)
//    {
//        std::cout<<i<<' ';
//    }
//    std::cout<<'\n';
//    for(int i = 0; i <= sis; i++)
//    {
//        std::cout<<visited2[i][0]<<' ';
//    }
//    std::cout<<'\n';
    for(int i = 0; i <= sis; i++)
    {
//        std::cout<<visited2[i][1]<<' ';
        rmq[0][i][0] = visited2[i][0];
        rmq[0][i][1] = visited2[i][1];
    }
//    std::cout<<'\n';

    for(int i = 1; (1<<i) <= n; i++)
    {
//        std::cout<<"leng: "<<(1<<i)<<'\n';
        for(int j = 0; j < sis - (1<<i) + 1; j++)
        {
            int leng = (1<<(i-1));
//            rmq[i][j][1] = min(rmq[i-1][j][1], rmq[i-1][j+(1<<i)][1]);
            min(rmq[i-1][j], rmq[i-1][j+leng], rmq[i][j][1], rmq[i][j][0]);
//            std::cout<<rmq[i][j][1]<<' ';
//            std::cout<<' '<<j<<' '<<j+(1<<i)<<": "<<rmq[i-1][j][1]<<' '<<rmq[i-1][j+(1<<i)][1]<<": "<<' '<<rmq[i][j][1]<<'\n';
//            std::cout<<i<<' '<<j<<' '<<rmq[i][j][0]<<' '<<rmq[i][j][1]<<'\n';
        }
//        std::cout<<'\n';
    }

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

//    std::cout<<'\n';

    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;
        int val1, val2;

//        std::cout<<min(rmq[lg[lung]][hashu[x].front()], rmq[lg[lung]][hashu[x].front() + lung - (1<<lg[lung])])<<'\n';
        min(rmq[lg[lung]][psst2], rmq[lg[lung]][psst2 + lung - (1<<lg[lung])], val1, val2);
        fout<<val2<<'\n';
//        std::cout<<psst2<<' '<<psst2 + lung - (1<<lg[lung])<<' '<<(1<<lg[lung])<<'\n';
//        std::cout<<rmq[lg[lung]][psst2][1] + 1<<' '<<rmq[lg[lung]][psst2 + lung - (1<<lg[lung])][1] + 1<<'\n';
//        std::cout<<x<<' '<<y<<": "<<psst2<<' '<<psst2 + lung - (1<<lg[lung])<<": "<<' '<<lung<<' '<<lg[lung]<<' '<<val1+1<<' '<<rmq[lg[lung]][psst2+lung-(1<<lg[lung])][1]<<'\n';
    }

//    for(int i = 2; i <= n; i++)
//    {
//        lg[i] = lg[i / 2] + 1;
//    }
//
//    for(int i = 1; (1<<i) <= n; i++)
//    {
//        for(int j = 0; j < n - (1<<i) + 1; j++)
//        {
//            for(int u = 0; u < n - (1<<i) + 1; u++)
//            {
//                int l = 1<<(i-1);
//                rmq[i][j][u] = max(rmq[i - 1][j][u], rmq[i - 1][j + l][u], rmq[i - 1][j + l][u + l], rmq[i - 1][j][u + l]);
//            }
//        }
//    }
//
//    int p1, p2, p3;
//    for(int i = 0; i < m; i++)
//    {
//        fin>>p1>>p2>>p3;
//        p1--;
//        p2--;
//        long long lung = (1<<lg[p3]);
//
//        fout<<max(rmq[lg[p3]][p1][p2], rmq[lg[p3]][p1+p3-lung][p2], rmq[lg[p3]][p1+p3-lung][p2+p3-lung], rmq[lg[p3]][p1][p2+p3-lung])<<'\n';
//    }

}

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