Pagini recente » Cod sursa (job #843055) | Cod sursa (job #2883597) | Cod sursa (job #2459278) | Cod sursa (job #1505911) | Cod sursa (job #1109428)
#include <fstream>
#include <vector>
#include <list>
using namespace std;
int n;
vector <list <int> > muchii;
vector <int> tdesc;
int nivele[200002];
int euler[200002];
int rmq[200001][18];
int lg[200001];
int tmax;
void dfs(int x, int niv) {
if(tdesc[x] == -1) tdesc[x] = tmax;
euler[tmax] = x;
nivele[x] = niv;
++tmax;
typedef list <int> li;
typedef li::iterator li_it;
for(li_it it = muchii[x].begin(); it != muchii[x].end(); ++it) {
dfs(*it, niv+1);
euler[++tmax] = x;
}
}
void precalc(void) {
tdesc.resize(n+1, -1);
tmax = 0;
dfs(1, 0);
lg[1] = 0;
for(int i = 2; i != tmax; ++i)
lg[i] = lg[i >> 1] + 1;
for(int i = 1; i <= tmax; ++i)
rmq[i][0] = euler[i];
for(int j = 1; j < lg[tmax]; ++j)
for(int i = 1; i + (1 << j) - 1 <= tmax; ++i) {
if(nivele[rmq[i][j-1]] < nivele[rmq[i + (1 << (j-1))][j-1]])
rmq[i][j] = rmq[i][j-1];
else
rmq[i][j] = rmq[i + (1 << (j-1))][j-1];
}
}
int lca(int x, int y) {
int a = min(tdesc[x], tdesc[y]);
int b = max(tdesc[x], tdesc[y]);
int pow = lg[b - a + 1];
if(nivele[rmq[a][pow]] < nivele[rmq[b - (1 << pow) + 1][pow]])
return rmq[a][pow];
else
return rmq[b - (1 << pow) + 1][pow];
}
int main(void) {
ifstream fin("lca.in");
int m;
fin >> n >> m;
muchii.resize(n+2);
for(int i = 1; i <= n; ++i) {
int x;
fin >> x;
muchii[x].push_back(i);
}
precalc();
ofstream fout("lca.out");
for(int i = 0; i < m; ++i) {
int a, b;
fin >> a >> b;
fout << lca(a, b);
}
fin.close();
fout.close();
}