Cod sursa(job #1082986)

Utilizator PsychoAlexAlexandru Buicescu PsychoAlex Data 15 ianuarie 2014 14:44:16
Problema Lowest Common Ancestor Scor 10
Compilator cpp Status done
Runda Arhiva educationala Marime 4.71 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];
//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::unordered_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 + 1;
        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);
        if(val2 == 0)
        {
            std::cout<<1<<'\n';
        }
        else
        {
            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;
}