Pagini recente » Cod sursa (job #2306482) | Cod sursa (job #1358490) | Cod sursa (job #1002301) | Cod sursa (job #1000409) | Cod sursa (job #2249475)
#include <bits/stdc++.h>
struct Tree {
int N;
std::vector<std::vector<int> > G;
// Basic tree statistics
int *label;
int *subarb, *depth;
int lastStatisticRoot;
Tree(int _N) : N(_N) {
G.resize(1+N);
label = subarb = depth = NULL;
lastStatisticRoot = 0;
}
void pushEdge(int a, int b) {
G[a].push_back(b);
G[b].push_back(a);
}
void statisticDfs(int root = 1, int father = 0) {
subarb[root] = 1;
for(auto it: G[root])
if(it != father) {
depth[it] = depth[root] + 1;
statisticDfs(it, root);
subarb[root] += subarb[it];
}
}
void calculateStatistics(int root = 1) {
if(subarb == NULL && depth == NULL) {
subarb = new int[1+N];
depth = new int[1+N];
}
if(lastStatisticRoot != root) {
memset(subarb, 0, sizeof(int) * (1 + N));
memset(depth, 0, sizeof(int) * (1 + N));
statisticDfs(root);
lastStatisticRoot = root;
}
}
void allocLabels() {
if(label == NULL)
label = new int[1+N];
memset(label, 0, sizeof(int) * (1 + N));
}
};
struct BinaryLifting {
Tree *T;
int maxlg, lastRoot;
int **ancestor;
BinaryLifting(Tree *_T):T(_T) {
maxlg = 0;
while((1 << maxlg) < T->N)
++maxlg;
ancestor = new int*[1+maxlg];
for(int i = 0; i <= maxlg; ++i)
ancestor[i] = new int[1 + T->N];
lastRoot = 0;
}
void ancestryDfs(int nod, int papa = 0) {
for(auto it: T->G[nod])
if(it != papa) {
ancestor[0][it] = nod;
ancestryDfs(it, nod);
}
for(int i = 1; i <= maxlg; ++i)
ancestor[i][nod] = ancestor[i - 1][ancestor[i - 1][nod]];
}
void computeAncestry(int root = 1) {
if(lastRoot != root) {
lastRoot = root;
ancestor[0][root] = 0;
ancestryDfs(1);
}
}
int goUp(int nod, int x) {
if(x >= T->N)
return 0;
for(int i = 0; i <= maxlg; ++i)
if((1 << i) & x)
nod = ancestor[i][nod];
return nod;
}
};
int main() {
FILE *fin = fopen("stramosi.in", "r");
FILE *fout = fopen("stramosi.out", "w");
int n, q;
Tree *T;
BinaryLifting *bl;
fscanf(fin, "%d%d", &n, &q);
T = new Tree(1+n);
for(int i = 2; i <= n + 1; ++i) {
int x;
fscanf(fin, "%d", &x);
T->pushEdge(x + 1, i);
}
bl = new BinaryLifting(T);
bl->computeAncestry(1);
for(int i = 1; i <= q; ++i) {
int nod, up;
fscanf(fin, "%d%d", &nod, &up);
fprintf(fout, "%d\n", std::max(0, bl->goUp(nod + 1, up) - 1));
}
fclose(fin);
fclose(fout);
return 0;
}