【题目来源】
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