Cod sursa(job #1525611)

Utilizator bogdanciurezubogdan ciurezu bogdanciurezu Data 15 noiembrie 2015 12:03:53
Problema Lowest Common Ancestor Scor 0
Compilator cpp Status done
Runda Arhiva educationala Marime 1.92 kb
#include <fstream>
#include <vector>

using namespace std;

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

const int nmax = 100050;
int n, m;
bool Frecv[2 * nmax];

vector < int > Graf[nmax], euler, niv, logaritm, prmAp;

int rmq[20][2 * nmax];

void parcEuler(int poz, int lvl){

    Frecv[poz] = true;
    euler.push_back(poz);
    niv[poz] = lvl;
    prmAp[poz] = euler.size();
    for(int i = 0; i < Graf[poz].size(); ++i){
        if( !Frecv[ Graf[poz][i] ] ){
            parcEuler( Graf[poz][i], lvl + 1 );
            euler.push_back(poz);
        }
    }
}

void rangeMinQuerry(){
    int s;

    for(int i = 1; (1 << i) <= euler.size(); ++i){
        for(int j = 1; j <= euler.size() - (1 << i) + 1; ++j){
            s = 1 << (i - 1);

            rmq[i][j] = niv[ rmq[i - 1][j] ] < niv[ rmq[i - 1][j + s] ] ? rmq[i - 1][j] : rmq[i - 1][j + s];
        }
    }
}

int main()
{
    f>>n>>m;
    niv.resize(n + 1, 0);
    prmAp.resize(n + 1, 0);

    for(int i = 2, x; i <= n; ++i){
        f>>x;

        Graf[x].push_back(i);
        Graf[i].push_back(x);
    }

   parcEuler(1, 0);

    for(int i = 0; i < euler.size(); ++i){
        rmq[0][i + 1] = euler[i];
    }
    rangeMinQuerry();

    logaritm.push_back(-1);
    for(int i = 1; i <= euler.size(); ++i) logaritm.push_back( logaritm[ (i >> 1) ] + 1 );

   /* for(int i = 0; (1 << i) <= euler.size(); ++i){
        for(int j = 1; j <= euler.size() - (1 << i) + 1; ++j){
            g<<rmq[i][j]<<' ';
        }
        g<<'\n';
    }*/

    int diff, trm1, trm2, sol;

    for(int i = 1, x, y; i <= m; ++i){
        f>>x>>y;
        diff = prmAp[y] - prmAp[x];
        if(diff < 0) diff *= -1;
        trm1 = rmq[ logaritm[diff] ][prmAp[x]];
        trm2 = rmq[ logaritm[diff] ][ prmAp[y] - ( 1 << logaritm[diff] ) + 1 ];
        sol = niv[trm1] < niv[trm2] ? trm1 : trm2;

       g<<sol<<'\n';
    }
    return 0;
}