Cod sursa(job #1810953)

Utilizator dragos_vecerdeaVecerdea Dragos dragos_vecerdea Data 20 noiembrie 2016 18:25:11
Problema Lowest Common Ancestor Scor 0
Compilator cpp Status done
Runda Arhiva educationala Marime 2.34 kb
#include <stdio.h>
#include <queue>
using namespace std;
FILE *fin = fopen("lca.in", "r");
FILE *fout = fopen("lca.out", "w");
int minim(int a, int b)
{
    if(a <= b) return a;
    return b;
}
int cmmp(int a, int b)
{
    int incadrez = b-a+1;
    int putere = 1;
    while(2*putere<=incadrez)
    {
        putere*=2;
    }
    return putere;
}
int coef(int a, int b)
{
    int incadrez = b-a+1;
    int putere = 1;
    int rand = 1;
    while(2*putere<=incadrez)
    {
        rand++;
        putere*=2;
    }
    return rand;
}
int corespondent[100001];
int n, m,q,nod1,nod2;
int answer[17][210001];
int invers[100001];
char vizitat[100001];
int cnt=1;
int nod;
int prima[210001];
vector <int> fii[100001];
vector <int> pEuler;
void euler(int nod)
{
    pEuler.push_back(corespondent[nod]);
    for(auto m : fii[nod])
    {
        euler(m);
        pEuler.push_back(corespondent[nod]);
    }
}
int main()
{

    fscanf(fin, "%d%d", &n, &q);
    for(int i = 1; i <= n-1; i ++)
    {
        fscanf(fin, "%d", &nod);
        fii[nod].push_back(i+1);
    }
    queue <int> frontiera;
    int start = 1;
    frontiera.push(start);
    while(!frontiera.empty())
    {
        nod=frontiera.front();
        frontiera.pop();
        corespondent[nod]=cnt;
        invers[cnt]=nod;
        cnt++;
        vizitat[nod]=1;
        for(auto m : fii[nod])
        {
            if(vizitat[m] == 0)
            {
                vizitat[m]=1;
                frontiera.push(m);
            }
        }
    }
    euler(1);
    cnt = 1;
    for(auto m : pEuler)
    {
        if(prima[m]==0) prima[m]=cnt;
        answer[1][cnt]=m;
        cnt++;
    }
    cnt--;
    m = cnt;
    int ad=1;
    for(int i = 2; i <= 17 ;i++)
    {
        for(int j = 1; j <= m; j++)
        {
            if(j+ad <= m)
            {
                answer[i][j]=minim(answer[i-1][j], answer[i-1][j+ad]);
            }
        }
        ad*=2;
    }
    for(int i = 1; i <= q; i++)
    {
        fscanf(fin, "%d%d", &nod1, &nod2);
        int x=prima[corespondent[nod1]];
        int y=prima[corespondent[nod2]];
        int diametru = cmmp(x , y);
        int coeficient = coef(x, y);
        fprintf(fout, "%d\n", invers[minim(answer[coeficient][x], answer[coeficient][y-diametru+1])]);
    }
    return 0;
}