519测试

已结束 IOI 开始于: 2026-5-19 18:00 3 小时 主持人: 11

519测试

#include <iostream>
#include <vector>
using namespace std;
const int N = 5e5+10;
vector<int> e[N];
int fa[N][20], dep[N];  //f[i][j]; 从i点向上跳2的j次方的点
int num[N][20];//从i点向上跳2的j次方的点与i号点的距离
void dfs(int a, int p){//p是a节点的父节点
    dep[a] = dep[p] + 1;//深度·
    fa[a][0] = p;
   // num[a][0]=2;
    for(int i = 1; i < 20; i++)//通过递推 来求出st数组
    {
        fa[a][i] = fa[fa[a][i-1]][i-1];
       // num[a][i]=num[a][i-1]+num[fa[a][i-1]][i-1];
    } 
    for(int x : e[a])//遍历 vector
        if(x != p) dfs(x, a);
}
int lca(int a, int b){//log(10000000) =23
    if(dep[a] < dep[b]) swap(a, b);//先保证让a深度大于等于b的深度
    for(int i = 19; i >= 0; i--){//如果a点的深度不等于b点的深度 就让a点向上跳            
        if(dep[fa[a][i]] >= dep[b]) a = fa[a][i];
        //a的深度 17 b点的深度是 11
      // 17-11=6; 8 4 2 1
   }
    if(a == b) return a;//a点b点一样 随便返回一个都是最近公共祖先
    for(int i = 19; i >= 0; i--){
        if(fa[a][i] != fa[b][i]){
            a = fa[a][i];
            b = fa[b][i];
        }
    }
    return fa[a][0];//直接返回最近公共祖先
}
int main(){
    ios::sync_with_stdio(0); cin.tie(0);
    int n, m, s; cin >> n >> m >> s;
    n--;
    while(--n){
        int a, b; cin >> a >> b;
        e[a].push_back(b); e[b].push_back(a);//邻接表
    }
    dfs(s, 0);
    while(m--){
        int a, b; cin >> a >> b;
        cout << lca(a, b) << endl;
    }
    return 0;
}
状态
已结束
规则
IOI
题目
4
开始于
2026-5-19 18:00
结束于
2026-5-19 21:00
持续时间
3 小时
主持人
参赛人数
11