Pagini recente » Cod sursa (job #2103218) | Clasament igorj_9 | Cod sursa (job #2961337) | Cod sursa (job #1743085) | Cod sursa (job #1481630)
#include <cstdio>
#include <vector>
#include <cstring>
using namespace std;
const int nmax = 100000;
struct Node
{
int dad;
vector <int> sons;
};
int power[2*nmax+5];
int lvl[2*nmax+5];
int first[nmax+5];
int Rmq[30][2*nmax+5];
class GRAPH
{
private:
int n, last;
vector <int> a[nmax+5];
vector <int> Euler;
public:
GRAPH(int N)
{
last=0;n=N;
memset(lvl, 0, sizeof(lvl));
memset(first, 0, sizeof(first));
}
void push(int x, int y)
{
a[x].push_back(y);
}
void dfs(int nod, int level)
{
if(first[nod] == 0)first[nod] = Euler.size();
lvl[Euler.size()] = level;
Euler.push_back(nod);
for(int i=0; i<a[nod].size(); i++)
{
dfs(a[nod][i], level+1);
lvl[Euler.size()] = level;
Euler.push_back(nod);
}
}
void rmq()
{
for(int i=0; i<Euler.size(); i++)
Rmq[0][i] = i;
for(int i=1; (1<<i)<Euler.size(); i++)
for(int j=0; j<Euler.size()-(1<<i); j++)
{
Rmq[i][j] = Rmq[i-1][j];
if(Euler[Rmq[i-1][j+(1<<(i-1))]] < Euler[Rmq[i][j]])
Rmq[i][j] = Rmq[i-1][j+(1<<(i-1))];
}
}
int lca(int x, int y)
{
if(first[x] > first[y])swap(x, y);
int a = first[x];
int b = first[y];
int l = power[b-a+1];
int ans = min(Euler[Rmq[l][a]], Euler[Rmq[l][b+1-(1<<l)]]);
return ans;
}
};
int main()
{
freopen("lca.in", "r", stdin);
freopen("lca.out", "w", stdout);
for(int i=2; i<=2*nmax; i++)
power[i] = power[i>>1]+1;
int n, m;
scanf("%d%d", &n, &m);
GRAPH G(n);
for(int i=1; i<n; i++)
{
int x;
scanf("%d", &x);
G.push(x, i+1);
}
G.dfs(1, 0);
G.rmq();
for(int i=0; i<m; i++)
{
int x, y;
scanf("%d%d", &x, &y);
printf("%d\n", G.lca(x, y));
}
return 0;
}