Mai intai trebuie sa te autentifici.

Cod sursa(job #2648554)

Utilizator Marius7122FMI Ciltea Marian Marius7122 Data 11 septembrie 2020 14:11:08
Problema Lowest Common Ancestor Scor 70
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.12 kb
#include <iostream>
#include <fstream>
#include <vector>

using namespace std;

/** Funcţiile necesare parsării fişierului de intrare **/
FILE *_fin;
int _in_loc; char _in_buff[4096];
 
 
void read_init(const char* nume) // Apelaţi această funcţie la începutul funcţiei <main>
{
	_fin = fopen(nume, "r");
	_in_loc = 4095;
}
 
inline char read_ch()
{
	++_in_loc;
	if (_in_loc == 4096) {
		_in_loc = 0;
		fread(_in_buff, 1, 4096, _fin);
	}
	return _in_buff[_in_loc];
}
 
inline int read_u32() // Apelaţi această funcţie pentru a citi un număr ce se încadrează în categoria <unsigned int>
{
	int u32 = 0; char c;
	while (!isdigit(c = read_ch()) && c != '-');
	int sgn = 1;
	if (c == '-') {
		sgn = -1;
	} else {
		u32 = c - '0';
	}
	while (isdigit(c = read_ch())) {
		u32 = u32 * 10 + c - '0';
	}
	return u32 * sgn;
}

 
// ifstream fin("lca.in");
ofstream fout("lca.out");
 
const int N = 100005;
const int LOG = 17;

int n, q;
int anc[LOG][N], d[N];
 
void computeDepth(int x)
{
    if(anc[0][x] == 0 || d[x])
        return;
    
    if(d[anc[0][x]] == 0 && anc[0][x] != 0)
        computeDepth(anc[0][x]);
    
    d[x] = d[anc[0][x]] + 1;

}

void precompute()
{
    for(int i = 1; i <= n; i++)
        computeDepth(i);

    for(int lvl = 1; (1 << lvl) <= n; lvl++)
        for(int i = 1; i <= n; i++)
            anc[lvl][i] = anc[lvl-1][anc[lvl-1][i]];
}

int solveQuery(int x, int y)
{
    if(d[x] < d[y])
        swap(x, y);

    // aducerea pe acelasi nivel
    int dif = d[x] - d[y];
    for(int lvl = 0; (1 << lvl) <= n; lvl++)
        if(dif & (1 << lvl))
            x = anc[lvl][x];

    // gasesc stramosul comun
    if(x == y)
        return x;
    for(int lvl = LOG - 1; lvl >= 0; lvl--)
        if(anc[lvl][x] != anc[lvl][y])
        {
            x = anc[lvl][x];
            y = anc[lvl][y];
        }
    return anc[0][x];
}

int main()
{
	read_init("lca.in");
    n = read_u32();
    q = read_u32();
    for(int i = 2; i <= n; i++)
        anc[0][i] = read_u32();

    precompute();
    while(q--)
    {
        int x, y;
        x = read_u32();
        y = read_u32();
        fout << solveQuery(x, y) << '\n';
    }
    return 0;
}