随笔 - 8,  文章 - 0,  评论 - 0,  阅读 - 1386
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
#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   ACMood  阅读(157)  评论(0)    收藏  举报
编辑推荐:
· 记一次 .NET某固高运动卡测试 卡慢分析
· 微服务架构学习与思考:微服务拆分的原则
· 记一次 .NET某云HIS系统 CPU爆高分析
· 如果单表数据量大,只能考虑分库分表吗?
· 一文彻底搞懂 MCP:AI 大模型的标准化工具箱
阅读排行:
· 博客园2025新款「AI繁忙」系列T恤上架
· Avalonia跨平台实战(二),Avalonia相比WPF的便利合集(一)
· C# LINQ 快速入门实战指南,建议收藏学习!
· Redis实现高并发场景下的计数器设计
· 上周热点回顾(4.7-4.13)

< 2025年4月 >
30 31 1 2 3 4 5
6 7 8 9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29 30 1 2 3
4 5 6 7 8 9 10
点击右上角即可分享
微信分享提示