P4549 【模板】裴蜀定理

题目传送门
前置知识:裴蜀定理

分析

对于输入的 n n n个数 a 1 a_1 a1 a 2 a_2 a2 a 3 ⋯ a n a_3\cdots a_n a3an,我们其实可以默认它们全部为非负数,因为对于 x i x_i xi,是可以取任意值的,所以当 a i a_i ai为负时, x i x_i xi取负数,两数之积就为正了,所以不用考虑判断 S < 0 S<0 S<0的情况。
接着,我们其实需要计算的就是 ∣ a 1 ∣ ⋅ x 1 + ∣ a 2 ∣ ⋅ x 2 + ∣ a 3 ∣ ⋅ x 3 + ⋯ + ∣ a n ∣ ⋅ x n \lvert a_1\lvert\cdot x_1+\lvert a_2\lvert\cdot x_2+\lvert a_3\lvert\cdot x_3+\cdots+\lvert a_n\lvert\cdot x_n a1x1+a2x2+a3x3++anxn
那么,又因为在裴蜀定理及其证明中说过裴蜀定理的推广:
对于多个整数 a 1 a_1 a1 a 2 a_2 a2 a 3 a_3 a3…… a n a_n an(不全为零),存在整数 x 1 x_1 x1 x 2 x_2 x2 x 3 x_3 x3…… x n x_n xn使得:
g c d ( gcd( gcd( a 1 a_1 a1 a 2 a_2 a2 a 3 a_3 a3…… a n a_n an ) = a 1 x 1 + a 2 x 2 + a 3 x 3 + )=a_1x_1+a_2x_2+a_3x_3+ )=a1x1+a2x2+a3x3+…… a n x n a_nx_n anxn a 1 x 1 + a 2 x 2 + a 3 x 3 + a_1x_1+a_2x_2+a_3x_3+ a1x1+a2x2+a3x3+…… a n x n a_nx_n anxn g c d ( gcd( gcd( a 1 a_1 a1 a 2 a_2 a2 a 3 a_3 a3…… a n a_n an ) ) )的倍数。
那么,原式就可以表示为: p ⋅ g c d ( ∣ a 1 ∣ , ∣ a 2 ∣ , ∣ a 3 ∣ , ⋯   , ∣ a n ∣ ) p\cdot gcd(\lvert a_1\lvert,\lvert a_2\lvert,\lvert a_3\lvert,\cdots,\lvert a_n\lvert) pgcd(∣a1,a2,a3,,an),当 S > 0 S>0 S>0时,要使 S S S最小, g c d ( ∣ a 1 ∣ , ∣ a 2 ∣ , ∣ a 3 ∣ , ⋯   , ∣ a n ∣ ) gcd(\lvert a_1\lvert,\lvert a_2\lvert,\lvert a_3\lvert,\cdots,\lvert a_n\lvert) gcd(∣a1,a2,a3,,an)为定值,那么 p p p取值为 1 1 1
所以,最后的答案就是所有 a [ i ] a[i] a[i]的最大公约数。

#include<bits/stdc++.h>
using namespace std;
const int N=1e6+5;
int read(){
	int x=0,f=1;
	char c=getchar();
	while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
	while(c>='0'&&c<='9')x=(x<<3)+(x<<1)+c-'0',c=getchar();
	return x*f;
}
void print(int x){
	if(x<0)putchar('-'),x=-x;
	if(x<10){putchar(x+'0');return;}
	print(x/10);
	putchar(x%10+'0');
}
int n,ans;
int a[N];
int gcd(int a,int b){//辗转相除法
	if(a<b)swap(a,b);
	if(b==0)return a;
	return gcd(b,a%b);
}
signed main(){
	n=read();
	for(int i=1;i<=n;i++)ans=gcd(ans,abs(read()));
	print(ans);
}
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值