Pagini recente » Cod sursa (job #2022977) | Cod sursa (job #1925968) | Cod sursa (job #2349561) | Cod sursa (job #1354477) | Cod sursa (job #3305095)
#include <bits/stdc++.h>
std::ifstream fin("stramosi.in");
std::ofstream fout("stramosi.out");
//#define fin std::cin
//#define fout std::cout
/*
Binary Lifting //& Liniarizarea arborelui//
--------------
Se da un arbore cu radacina cu N noduri si Q intrebari de forma:
(x, k) - care este cel de-al k-lea stramos al nodului x
Folosind father[i] si mergand in sus avem O(N) pe query, insa avem nevoie de o complexitate mai buna,
precum O(log(n)):
-> binary search <-> nu putem aplica cautarea binara
-> divide et impera <-> nu putem combina subprobleme
-> puteri de 2
As putea avea anc[x][i] = al 2^i -lea stramos al nodului x
-> orice numar k poate fi scris ca suma de puteri de 2
OBS: Putem construi tabloul in timpul unui DFS sau folosing 2 for-uri (for exp... for node)
//OBS: Daca avem mai multe arbori putem crea o radacina -1 de care se leaga toate radacinile.
// Daca LCA-ul este -1 atunci acesta nu exista.
*/
const int nmax = 250005;
const int lognmax = 19;
int n, q;
std::vector<int> graph[nmax];
int father[nmax];
int anc[lognmax][nmax];
/*
void dfs(int node, int parent)
{
anc[0][node] = parent;
for(int i = 1; i < lognmax; ++i)
anc[i][node] = anc[i - 1][anc[i - 1][node]];
for(auto adj : graph[node])
if(adj != parent)
dfs(adj, node);
}
*/
int query(int node, int k)
{
int answer = node;
for(int i = lognmax - 1; i >= 0 && answer != 0; --i)
if(k >= (1 << i))
answer = anc[i][answer], k -= (1 << i);
return answer;
}
int main()
{
fin >> n >> q;
for(int i = 1; i <= n; ++i)
{
fin >> father[i];
graph[i].push_back(father[i]);
graph[father[i]].push_back(i);
}
// Metoda 1:
for(int i = 1; i <= n; ++i)
anc[0][i] = father[i];
for(int i = 1; i < lognmax; ++i)
for(int x = 1; x <= n; ++x)
anc[i][x] = anc[i - 1][anc[i - 1][x]]; // 2^i = 2^(i - 1) + 2^(i - 1)
// Metoda 2: (90p, ia TLE datorita DFS-ului)
/*
for(int i = 1; i <= n; ++i)
if(father[i] == 0) // radacina
dfs(i, 0);
*/
for(int i = 1; i <= q; ++i)
{
int x, k;
fin >> x >> k;
fout << query(x, k) << "\n";
}
return 0;
}