专栏文章

题解:P13014 [GESP202506 五级] 最大公因数

P13014题解参与者 11已保存评论 11

文章操作

快速查看文章及其快照的属性,并进行相关操作。

当前评论
11 条
当前快照
1 份
快照标识符
@mip0e0l7
此快照首次捕获于
2025/12/03 04:06
3 个月前
此快照最后确认于
2025/12/03 04:06
3 个月前
查看原文

题意

给定 nn 个正整数 a1,a2,,ana_1,a_2,\dots,a_n 以及 qq 组询问。对于第 i(1iq)i(1 \le i \le q) 组询问,求出 gcd(a1+i,a2+i,,an+i)\gcd(a_1+i,a_2+i,\dots,a_n+i)。然而暴力会 TLE。

方法

注意到最大公因数有以下性质:
gcd(a1+i,a2+i,,an+i)=gcd(a1+i,(a2a1),(a3a1),,(ana1))\gcd(a_1+i, a_2+i, \dots, a_n+i) = \gcd(a_1+i, (a_2 - a_1), (a_3 - a_1), \dots, (a_n - a_1))
这是因为:
gcd(a+i,b+i)=gcd(a+i,(b+i)(a+i))=gcd(a+i,ba)\gcd(a+i, b+i) = \gcd(a+i, (b+i) - (a+i)) = \gcd(a+i, b-a)
这个性质可以推广到多个数的情况。
所以计算所有 aja1a_j - a_1j2j \geq 2)的最大公因数,记为 dd。 这样就将问题简化为计算 gcd(a1+i,d)\gcd(a_1 + i, d)。对于每个查询 ii,计算该柿子即可。
最后直接输出结果。

代码

CPP
#include<bits/stdc++.h>
using namespace std;
int n, q,a[100005],d;
int main() {
	scanf("%d%d",&n,&q);
	for (int i=1;i<=n;i++)
		scanf("%d", &a[i]);
	sort(a+1,a+n+1);
	for (int i=2;i<=n;i++)
		d=__gcd(d,a[i]-a[i - 1]);//根据 gcd 的性质计算 d
	for (int i=1;i<=q;i++)
		printf("%d\n",__gcd(d,a[1]+i));//输出时直接套公式
	return 0;
}

评论

11 条评论,欢迎与作者交流。

正在加载评论...