Pagini recente » Cod sursa (job #2296069) | Diferente pentru newsletter/summer-2009-1 intre reviziile 19 si 20 | Cod sursa (job #2712499) | Cod sursa (job #788949)
Cod sursa(job #788949)
#include<fstream>
#include<vector>
using namespace std;
ifstream fin("lca.in"); ofstream fout("lca.out");
int n, m, tata[100001], niv[100001], pos[100001], Log[400001], rmq[100001][20];
vector <int> fiu[100001], e;
void Parcurgere_Euler(int v){
if (!pos[v]) pos[v] = e.size();
niv[e.size()] = niv[e.size() - 1] + 1;
e.push_back(v);
for (int i = 0; i < fiu[v].size(); i++){
Parcurgere_Euler(fiu[v][i]);
niv[e.size()] = niv[e.size() - 1] - 1;
e.push_back(v);
}
}
void Build_RMQ(){
int i, j, L;
for (i = 0; i < e.size(); i++) rmq[i][0] = i;
for (j = 1, L = 2; L < e.size(); L = 1 << ++j)
for (i = 0; i < e.size() - L; i++)
rmq[i][j] = niv[rmq[i][j-1]] < niv[rmq[i + L / 2][j - 1]] ? rmq[i][j-1] : rmq[i + L / 2][j - 1];
}
int Get_Min(int p, int q){
if (p > q) swap(p, q);
int l = rmq[p][Log[q - p]];
int r = rmq[q - (1 << Log[q - p]) + 1][Log[q - p]];
return niv[l] < niv[r] ? e[l] : e[r];
}
int main(){
int i, v1, v2;
fin >> n >> m;
for (i = 2; i <= n; i++)
fin >> tata[i], fiu[tata[i]].push_back(i);
Parcurgere_Euler(1);
for (Log[1] = 0, i = 2; i < e.size(); i++) Log[i] = Log[i / 2] + 1;
Build_RMQ();
for (i = 0; i < m; i++){
fin >> v1 >> v2;
fout << Get_Min(pos[v1], pos[v2]) << "\n";
}
}