#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
using namespace std;

const int M = 200005;
struct Edge{
    int v, next;
} edge[M << 1];
int E; int head[M];
void add_edge(int s, int v){
    edge[E].next = head[s];
    edge[E].v = v;
    head[s] = E ++;
}
int fa[M][23];

int deep[M];
int vis[M];
int sum[M];

void bfs(){
    queue<int> q;
    q.push(1);
    memset(vis, 0, sizeof(vis));
    memset(sum, 0, sizeof(sum));
    fa[1][0] = 1;
    deep[1] = 0;
    vis[1] = 1;
    sum[1] = 1;
    while(!q.empty()){
        int u = q.front(); q.pop();
        for(int j = 1; j <= 20; j ++) {
            fa[u][j] = fa[fa[u][j-1]][j-1];
        }
        for(int i = head[u]; i != -1; i = edge[i].next){
            int v = edge[i].v;
            if(vis[v]) continue;
            sum[v] = sum[u] + 1;
            vis[v] = 1;

            fa[v][0] = u;
            deep[v] = deep[u] + 1;
            q.push(v);
        }
    }
}

int lca(int a, int b){
    if(deep[a] > deep[b]) swap(a, b);
    int ta = a; int tb = b;
    int da = deep[a]; int db = deep[b];
    for(int i = 0, dd = db - da; dd; dd >>= 1, i ++){
        if(dd&1)
            tb = fa[tb][i];
    }
    if(tb == ta) return tb;
    for(int i = 20; i >= 0; i --){
        if(fa[ta][i] == fa[tb][i]) continue;
        ta = fa[ta][i];
        tb = fa[tb][i];
    }
    return fa[ta][0];

}

int main(){
    int n, m;
    scanf("%d%d", &n, &m);
    int a, b;
    memset(head, -1, sizeof(head));
    for(int i = 2; i <= n; i ++){
        scanf("%d", &a);
        add_edge(a, i);
        add_edge(i, a);
    }
    bfs();
    while(m --){
        scanf("%d%d", &a, &b);
        int lc = lca(a, b);
        if(deep[lc] == deep[a])
            printf("%d %d\n", sum[lc], sum[b] - sum[lc]);
        else if(deep[lc] == deep[b]){
            printf("%d %d\n", sum[a] - sum[lc], sum[lc]);
        }else {
            printf("%d %d\n", sum[a], sum[b] - sum[lc]);
        }
    }
    return 0;
}

  

posted on 2015-05-29 08:32  ACMood  阅读(156)  评论(0编辑  收藏  举报