洛谷 P13016:[GESP202506 六级] 最大因数

【题目来源】
https://www.luogu.com.cn/problem/P13016

【题目描述】
给定一棵有 10^9 个结点的有根树,这些结点依次以 1,2,...,10^9 编号,根结点的编号为 1。对于编号为 k(2≤k≤10^9)的结点,其父结点的编号为 k 的因数中除 k 以外最大的因数。
现在有 q 组询问,第 i(1≤i≤q)组询问给定 xi, yi,请你求出编号分别为 xi, yi 的两个结点在这棵树上的距离。两个结点之间的距离是连接这两个结点的简单路径所包含的边数。

【输入格式】
第一行,一个正整数 q,表示询问组数。
接下来 q 行,每行两个正整数 xi,yi,表示询问结点的编号。

【输出格式】
输出共 q 行,每行一个整数,表示结点 xi,yi 之间的距离。

【输入样例1】
3
1 3
2 5
4 8

【输出样例1】
1
2
1

【输入样例2】
1
120 650

【输出样例2】
9

【说明/提示】
对于 60% 的测试点,保证 1≤xi,yi≤1000。
对于所有测试点,保证 1≤q≤1000,1≤xi,yi≤10^9。

【算法分析】
本质是计算两个数通过特定操作达到相同值的最小步骤数。

【算法代码】

cpp 复制代码
#include <bits/stdc++.h>
using namespace std;

map<int,int> mp;

int f(int x) {
    if(mp[x]>0) return mp[x];
    for(int i=2; i*i<=x; i++) {
        if(x%i==0) {
            mp[x]=x/i;
            return mp[x];
        }
    }
    return mp[x]=1;
}

int main() {
    int x,y,q;
    cin>>q;
    while(q--) {
        cin>>x>>y;
        int dis=0;
        while(x!=y) {
            if(x>y)  x=f(x);
            else y=f(y);
            dis++;
        }
        cout<<dis<<endl;
    }
    return 0;
}

/*
in:
3
1 3
2 5
4 8

out:
1
2
1
*/

【参考文献】
https://ccgao.blog.csdn.net/article/details/149142871
https://blog.csdn.net/qq_36230375/article/details/134934479