Pagini recente » Cod sursa (job #782) | Cod sursa (job #1355718) | Cod sursa (job #2907315) | Cod sursa (job #1336167) | Cod sursa (job #1674530)
#include <cstdio>
#include <queue>
using namespace std;
const int N_max = 250002;
const int M_max = 300002;
const int Log = 18;
int lst[N_max];
int urm[N_max];
int vf[N_max];
int nr;
int level[N_max];
bool viz[N_max];
int A[Log][N_max]; /* A[i][j] == AL 2 ^ i STRAMOS AL LUI j */
int Lg[N_max];
queue <int> C;
int N, Q;
void adauga(int x, int y)
{
// ADAUGA IN LISTA LUI x PE y
nr++;
vf[nr] = y;
urm[nr] = lst[x];
lst[x] = nr;
}
/*
void dfs(int x)
{
int p, y;
viz[x] = true;
// PARCURG VECINII y AI LUI x
p = lst[x];
while(p != 0)
{
y = vf[p];
if(!viz[y])
{
level[y] = 1 + level[x];
dfs(y);
}
p = urm[p];
}
}
*/
void BFS()
{
int i, p, y, x;
for(i = 1; i <= N; i++) level[i] = -1;
// INSEREZ IN COADA NODURILE TATA
for(i = 1; i <= N; i++)
if(!A[0][i])
{
C.push(i);
level[i] = 0;
}
while(!C.empty())
{
x = C.front();
C.pop();
// PARCURG VECINII y AI LUI x
p = lst[x];
while(p != 0)
{
y = vf[p];
if(level[y] == -1)
{
level[y] = 1 + level[x];
C.push(y);
}
p = urm[p];
}
}
}
void read()
{
freopen("stramosi.in", "r", stdin);
int i, j;
scanf("%d %d", &N, &Q);
for(i = 1; i <= N; i++)
{
scanf("%d", &A[0][i]); /* PRIMUL STRAMOS AL NODULUI i ESTE CHIAR TATAL ACESTUIA */
adauga(A[0][i], i);
}
/*
for(i = 1; i <= N; i++)
if(!A[0][i]) dfs(i);
*/
BFS();
/* CONSTRUIESC MATRICEA A */
for(i = 1; (1 << i) <= N; i++)
for(j = 1; j <= N; j++)
/* RECURENTA */
if(A[i - 1][j]) A[i][j] = A[ i - 1 ][ A[i - 1][j] ];
/* CONSTRUIESC VECTORUL Lg */
Lg[1] = 0;
for(i = 2; i <= N; i++) Lg[i] = 1 + Lg[i/2];
}
int query()
{
int j, node, P, L, lg;
scanf("%d %d", &node, &P);
if(P == 0) return node;
L = level[node] - P;
if(L < 0) return 0;
lg = Lg[level[node]];
for(j = lg; j >= 0; j--)
if(A[j][node] && level[A[j][node]] >= L) node = A[j][node];
/* ACUM NODUL node SE AFLA PE NIVELUL L. AFISEZ SOLUTIA */
return node;
}
int main()
{
freopen("stramosi.out", "w", stdout);
read();
for(int i = 1; i <= Q; i++) printf("%d\n", query());
return 0;
}