Pagini recente » Cod sursa (job #922827) | Cod sursa (job #2440586) | Cod sursa (job #1643958) | Cod sursa (job #1823802) | Cod sursa (job #634977)
Cod sursa(job #634977)
#include<cstdio>
#define N 100005
int max(int a, int b) {
if(a > b) return a;
return b;
}
int powof2[25];
int M[18][4*N];
int arrH[4*N] = {0,};
int arrV[4*N] = {0,};
int posInEuler[N];
int LG[4*N];
struct Node {
Node() {
noOfSons = 0;
sz = 100;
sons = new Node*[100];
for(int i = 0; i < 100; i++)
sons[i] = 0;
}
int noOfSons;
int sz;
char v;
Node** sons;
void resize(int newsz) {
int realnewsz = max(newsz, 2 * sz);
Node** news = new Node*[realnewsz];
for(int i = 0; i < noOfSons; i++)
news[i] = sons[i];
for(int i = noOfSons; i < realnewsz; i++)
news[i] = 0;
sons = news;
}
};
struct LNode {
int v;
int level;
LNode* next;
};
LNode* endOfList(LNode* h) {
LNode* hea = h;
while(hea -> next != 0) {
hea = hea -> next;
}
return hea;
}
LNode* eulerTour(Node* r, int l) {
if(r != 0) {
LNode* b1 = new LNode();
b1 -> v = r -> v;
b1 -> level = l;
b1 -> next = 0 ;
LNode* b2,*ant = 0;
for(int i = 0; i < r -> noOfSons; i++) {
b2 = new LNode();
b2 -> v = r -> v;
b2 -> level = l;
b2 -> next = 0;
LNode* fl = eulerTour(r -> sons[i], l + 1);
if (ant != 0) ant -> next = fl;
if(i == 0) b1 -> next = fl;
endOfList(fl) -> next = b2;
ant = b2;
}
return b1;
}
return 0;
}
Node* convertToSon(int p[], int n) {
Node** r = new Node*[n + 2];
for(int i = 1; i <= n; i++) {
r[i] = new Node();
r[i] -> v = i;
}
for(int i = 2; i <= n; i++) {
if(r[p[i]]->noOfSons >= r[p[i]]->sz)
r[p[i]]->resize(r[p[i]]->noOfSons + 2);
r[p[i]]->sons[r[p[i]]->noOfSons] = r[i];
r[p[i]]->noOfSons++;
}
Node* aux = r[1];
delete[] r;
return aux;
}
int min(int a, int b) {
if(a < b) return a;
return b;
}
void init(int k) {
for(int i = 0, p = 1; i < 19; i++, p*=2)
powof2[i] = p;
for(int i = 2; i <= k; i++)
LG[i] = LG[i / 2] + 1;
}
void RMQ(LNode* lh, int p) {
int nr = 0;
LNode* aux = lh;
while(aux != 0) {
nr++;
arrH[++arrH[0]] = aux -> level;
arrV[++arrV[0]] = aux -> v;
M[0][nr] = nr;
if(posInEuler[aux->v] == 0)
posInEuler[aux->v] = nr;
aux = aux -> next;
}
init(nr);
for(int i = 1; i <= 18; i++) {
int wh2go = nr - powof2[i] + 1;
for(int j = 1; j <= wh2go; j++)
if (arrH[M[i-1][j]] < arrH[M[i-1][j + powof2[i-1]]])
M[i][j] = M[i-1][j];
else
M[i][j] = M[i-1][j + powof2[i-1]];
}
for(int i = 1; i <= p; i++) {
int x, y;
scanf("%d %d",&x,&y);
int lf = posInEuler[x];
int right = posInEuler[y];
if(lf > right) {
lf = posInEuler[y];
right = posInEuler[x];
}
int how = right - lf + 1;
int p = LG[how];
if(arrH[M[p][lf]] < arrH[M[p][right-powof2[p] + 1]])
printf("%d\n",arrV[M[p][lf]]);
else
printf("%d\n",arrV[M[p][right-powof2[p] + 1]]);
}
}
int main() {
int n, m;
int p[N];
freopen("lca.in","r",stdin);
freopen("lca.out","w",stdout);
scanf("%d %d",&n,&m);
for(int i = 2; i <= n; i++)
scanf("%d", &p[i]);
Node* r = convertToSon(p, n);
LNode* z = eulerTour(r, 0);
RMQ(z, m);
return 0;
}