Cod sursa(job #3354050)

Utilizator Alexutu008Ionita Alexandru-Dumitru Alexutu008 Data 14 mai 2026 13:59:40
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.41 kb
#include <bits/stdc++.h>

using namespace std;


const int BUFSIZE = (1 << 16);

class InParser {
private:
	FILE* fin;
	char* buff;
	int sp;

	char read_ch() {
		++sp;
		if (sp == BUFSIZE) {
			sp = 0;
			fread(buff, 1, BUFSIZE, fin);
		}
		return buff[sp];
	}

public:
	InParser(const char* nume) {
		fin = fopen(nume, "r");
		buff = new char[BUFSIZE]();
		sp = BUFSIZE - 1;
	}

	InParser& operator >> (int& n) {
		char c;
		while (!isdigit(c = read_ch()));
		n = 0;
		do {
			n = 10 * n + c - '0';
		} while (isdigit(c = read_ch()));
		return *this;
	}
};
class OutParser {
private:
	FILE* fout;
	char* buff;
	int sp;

	void write_ch(char ch) {
		if (sp == BUFSIZE) {
			fwrite(buff, 1, BUFSIZE, fout);
			sp = 0;
			buff[sp++] = ch;
		}
		else {
			buff[sp++] = ch;
		}
	}


public:
	OutParser(const char* name) {
		fout = fopen(name, "w");
		buff = new char[BUFSIZE]();
		sp = 0;
	}
	~OutParser() {
		fwrite(buff, 1, sp, fout);
		fclose(fout);
	}

	OutParser& operator << (int vu32) {
		if (vu32 <= 9) {
			write_ch(vu32 + '0');
		}
		else {
			(*this) << (vu32 / 10);
			write_ch(vu32 % 10 + '0');
		}
		return *this;
	}


	OutParser& operator << (char ch) {
		write_ch(ch);
		return *this;
	}
};

const int N = 1e5 + 1, E = 19;

int n, q, lvl[N], lg[N];
int t[E][N]; // [i, j] -> stramosul lui j la dist 2**j
vector<int> mc[N];

void dfs(int nod) {
	for (auto& i : mc[nod]) {
		lvl[i] = lvl[nod] + 1;
		dfs(i);
	}
}

int anc(int nod, int ord) {
	for (int bit = 0; (1 << bit) <= ord; ++bit) {
		if ((1 << bit) & ord) {
			nod = t[bit][nod];
		}
	}

	return nod;
}

int lca(int x, int y) {
	int e = lg[lvl[x]];

	while (e >= 0) {
		if (t[e][x] != t[e][y]) {
			x = t[e][x];
			y = t[e][y];
		}
		--e;
	}

	return t[0][x];
}

int main() {
	InParser cin("lca.in");
	OutParser cout("lca.out");

	cin >> n >> q;
	for (int i = 2; i <= n; ++i) {
		int x; cin >> x;

		mc[x].push_back(i);
		t[0][i] = x;
	}

	dfs(1);

	for (int i = 2; i < N; ++i) lg[i] = lg[i / 2] + 1;

	for (int e = 1; e < E; ++e) {
		for (int nod = 1; nod <= n; ++nod) {
			t[e][nod] = t[e - 1][t[e - 1][nod]];
		}
	}

	while (q--) {
		int x, y; cin >> x >> y;

		if (lvl[x] > lvl[y]) swap(x, y);

		y = anc(y, lvl[y] - lvl[x]);

		if (x == y) {
			cout << x << '\n';
		}
		else {
			cout << lca(x, y) << '\n';
		}
	}

	return 0;
}