Pagini recente » Cod sursa (job #1684766) | Cod sursa (job #2071519) | Cod sursa (job #493006) | Cod sursa (job #2150764) | Cod sursa (job #2003624)
#include<cstdio>
#include<vector>
#include<algorithm>
#include<cctype>
#define MAX_N 100000
#define MAX_LOG 20
#define buf_SIZE 1 << 19
using namespace std;
int niv[2*MAX_N+1], E[2*MAX_N+1], ap[MAX_N+1], sparse[2*MAX_N+1][MAX_LOG];
int n, m, k, pos = buf_SIZE;
char buf[buf_SIZE];
vector<int> G[MAX_N+1];
inline char getChar(FILE *fin)
{
if(pos == buf_SIZE)
{
fread(buf,1,buf_SIZE,fin);
pos = 0;
}
return buf[pos++];
}
inline int read(FILE *fin)
{
int res = 0;
char ch;
do
{
ch = getChar(fin);
}while(!isdigit(ch));
do
{
res = 10*res + ch - '0';
ch = getChar(fin);
}while(isdigit(ch));
return res;
}
inline int log(int x)
{
return 31 - __builtin_clz(x);
}
void DFS(int node, int level)
{
E[k] = node;
niv[k] = level;
ap[node] = k;
k++;
vector<int> :: iterator it;
for(it = G[node].begin(); it != G[node].end(); it++)
{
DFS(*it,level+1);
E[k] = node;
niv[k] = level;
k++;
}
}
void RMQ()
{
int i, j;
for(i=0; i<k; i++)
sparse[i][0] = i;
for(j=1; (1 << j) <= k; j++)
for(i=0; i + (1 << j) - 1 < k; i++)
if(niv[sparse[i][j-1]] < niv[sparse[i + (1 << (j-1))][j-1]])
sparse[i][j] = sparse[i][j-1];
else sparse[i][j] = sparse[i + (1 << (j-1))][j-1];
}
int LCA(int x, int y)
{
int low, high, z, l, result;
low = ap[x];
high = ap[y];
if(low > high) swap(low,high);
l = high - low + 1;
z = log(l);
if(niv[sparse[low][z]] < niv[sparse[low + l - (1 << z)][z]])
result = sparse[low][z];
else result = sparse[low + l - (1 << z)][z];
return E[result];
}
int main()
{
int i, x, y;
FILE *fin, *fout;
fin = fopen("lca.in","r");
fout = fopen("lca.out","w");
n = read(fin); m = read(fin);
for(i=2; i<=n; i++)
{
x = read(fin);
G[x].push_back(i);
}
DFS(1,0);
RMQ();
for(i=1; i<=m; i++)
{
x = read(fin); y = read(fin);
fprintf(fout,"%d\n",LCA(x,y));
}
fclose(fin);
fclose(fout);
return 0;
}