✏️ 纠错
第 135 题 / 共 155 题
题目描述
给定一棵有 109 个结点的有根树,这些结点依次以 1,2,…,109 编号,根结点的编号为 1。对于编号为 k(2≤k≤109)的结点,其父结点的编号为 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≤109。
你真棒!
📝 题目解析
【题目大意】在一棵树上,每个节点的祖先被定义为该节点自身以外的最大因数,现需求解树上任意两点之间的距离。 根据数据范围要求,最大因数不包含此数,最小因数不包含1。
【考纲知识点】数学知识
【解题思路】从小到大找到所有的因数,然后从x起,x除以最小的因数得到了x的父亲节点x’“除x本身外最大的因数”,然后x’再除以第二小的因数得到x’的父亲节点。在此期间,统计因数的个数,相加即可得到结果。注意是多组测试数据。
参考程序
#include <cstdio>
#include <algorithm>
using namespace std;
const int N = 50;
int q;
int a[N], cnta;
int b[N], cntb;
int f[N], t;
void factorize(int x, int a[], int &cnt) {
a[0] = x;
t = 0;
for (int i = 2; i * i <= x; i++)
while (x % i == 0) {
f[++t] = i;
x /= i;
}
if (x > 1)
f[++t] = x;
for (int i = 1; i <= t; i++)
a[i] = a[i - 1] / f[i];
cnt = t;
}
int main() {
scanf("%d", &q);
while (q--) {
int x, y;
scanf("%d%d", &x, &y);
factorize(x, a, cnta);
factorize(y, b, cntb);
int px = 0, py = 0;
while (a[px] != b[py]) {
if (a[px] > b[py])
px++;
else
py++;
}
printf("%d\n", px + py);
}
return 0;
}