Pagini recente » Cod sursa (job #2572959) | Cod sursa (job #1315041) | Cod sursa (job #956424) | Cod sursa (job #1369156) | Cod sursa (job #2249486)
#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 N;
int maxlg, lastRoot;
int **ancestor;
BinaryLifting(int n) {
N = n;
maxlg = 0;
while((1 << maxlg) < N)
++maxlg;
ancestor = new int*[1+maxlg];
for(int i = 0; i <= maxlg; ++i) {
ancestor[i] = new int[1 + N];
memset(ancestor[i], 0, sizeof(int) * (1 + N));
}
}
BinaryLifting(Tree *_T):T(_T) {
N = T->N;
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];
memset(ancestor[i], 0, sizeof(int) * (1 + T->N));
}
lastRoot = 0;
}
void ancestryDfs(int nod, int papa = 0) {
ancestor[0][nod] = papa;
for(int i = 1; i <= maxlg; ++i)
ancestor[i][nod] = ancestor[i - 1][ancestor[i - 1][nod]];
for(auto it: T->G[nod])
if(it != papa)
ancestryDfs(it, nod);
}
void setAncestor(int nod, int anc) {
ancestor[0][nod] = anc;
}
void resetAncestor(int nod, int anc) {
ancestor[0][nod] = anc;
for(int i = 1; i <= maxlg; ++i)
ancestor[i][nod] = ancestor[i - 1][ancestor[i - 1][nod]];
}
void ancestryLiniar() {
for(int i = 1; i <= maxlg; ++i)
for(int nod = 1; nod <= N; ++nod)
ancestor[i][nod] = ancestor[i - 1][ancestor[i - 1][nod]];
}
void computeAncestry(int root = 1) {
if(T == NULL) {
ancestryLiniar();
} else if(lastRoot != root) {
lastRoot = root;
ancestor[0][root] = 0;
ancestryDfs(1);
}
}
int goUp(int nod, int x) {
if(x >= 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;
BinaryLifting *bl;
fscanf(fin, "%d%d", &n, &q);
bl = new BinaryLifting(n);
for(int i = 1; i <= n; ++i) {
int x;
fscanf(fin, "%d", &x);
bl->setAncestor(i, x);
}
bl->computeAncestry(1);
for(int i = 1; i <= q; ++i) {
int nod, up;
fscanf(fin, "%d%d", &nod, &up);
fprintf(fout, "%d\n", bl->goUp(nod, up));
}
fclose(fin);
fclose(fout);
return 0;
}