[CP / Codeforces] B. Playing with GCD (Div. 2)

B. Playing with GCD


分析

尽管难度只有 1200*,不过是一道很有意思的题目,而且我的水平也就 1300*

题目大意是给你一个有 n 个元素的数组 a,让你判断是否存在数组 b 使得 ai=gcd(bi,bi+1) 恒成立。

一开始我毫无思路。

这种情况持续了至少半个小时。

不过,总得有思路吧?

我想,最笨的方法,能不能一个元素一个元素地把数组 b 构造出来?

就比如对于 a1,肯定可以找到 b1b2,使 a1=gcd(b1,b2) 成立,比如取 b1=a1b2=2a1

接下来,我们需要构造合适的 b3,使得 a2=gcd(b2,b3),其中 a2,b2 都已确定。

问题来了,b2 是我们根据 a1 构造的,它只包含有关 a1 的信息,而且我们不能修改它——它是已经确定的值。那么,很有可能会出现这种情况:无论如何选取 b3,都无法满足 a2=gcd(b2,b3)。话虽如此,我们却不能断定数组 b 不存在,如果更换初始构造的 b1,b2,或许又会存在合法的 b3……

我得出结论:“一个元素一个元素地把数组 b 构造出来” 并不可行。为什么?因为初始条件太难确定了。一开始选择的 b1,b2 会影响到后续全部元素的构造,借用动态规划的术语,就是“有后效性”。

转换思路。我们的目标是“判断是否存在满足条件的数组 b”。如果能将这一目标等价转换为更容易判断的形式,就能解决此问题。

因此,需要观察数组 b 的性质。用英文来说,我们需要 "make observations"。(如果你经常看 Codeforces 的官方题解,或是一些外国教材、论文等,你会发现 "observation" 这个词出现得很频繁。很多时候,当结论或是推论并不是那么显而易见时,切中要害的 observation 就非常关键!)

Observation 1:lcm(ai,ai+1)|bi+1

由题目要求得 ai=gcd(bi,bi+1), ai+1=gcd(bi+1,bi+2)
注意到 bi+1 在两个式子里都出现了,所以 ai,ai+1 都是 bi+1 的因子,那么就有 lcm(ai,ai+1)|bi+1

Observation 2:ai=gcd(lcm(ai1,ai),lcm(ai,ai+1))

由前一个 observation 我们知道 bi+1 可以写成形如 lcm(ai,ai+1)x 的形式,其中 x 是一个正整数。

代入题目要求的式子,有:

ai=gcd(bi,bi+1)ai=gcd(lcm(ai1,ai)x,lcm(ai,ai+1)y)

关键的一步来了。我们知道:两个数的最大公因数是它们的公因数中最大的那个(好像什么都没说),而 ai 正是 lcm(ai1,ai)lcm(ai,ai+1) 的公因数,所以 gcd(lcm(ai1,ai),lcm(ai,ai+1))ai

分类讨论:

如果 gcd(lcm(ai1,ai),lcm(ai,ai+1))=ai,很好,正是所我们期待的结果,只需令 x=1,y=1 即可,此时 bi=lcm(ai1,ai)bi+1=lcm(ai,ai+1)

如果 gcd(lcm(ai1,ai),lcm(ai,ai+1))>ai,那么就有 gcd(lcm(ai1,ai)x,lcm(ai,ai+1)y)>ai,也就是说,无论如何选择 x,y 都没法让 ai=gcd(lcm(ai1,ai)x,lcm(ai,ai+1)y) 成立。

综上,如果存在满足题目要求的数组 b,那么必有 ai=gcd(lcm(ai1,ai),lcm(ai,ai+1)),这是充要条件。

得到下面的代码:

代码

void solve() {
int n;
std::cin >> n;
std::vector<int> v(n);
for (int i = 0; i < n; i++) {
std::cin >> v[i];
}
for (int i = 1; i < n - 1; i++) {
if (std::gcd(std::lcm(v[i - 1], v[i]),
std::lcm(v[i], v[i + 1])) != v[i]) {
std::cout << "NO\n";
return;
}
}
std::cout << "YES\n";
}
posted @   ZXPrism  阅读(12)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· winform 绘制太阳,地球,月球 运作规律
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
点击右上角即可分享
微信分享提示