分析
对于输入的
n
n
n个数
a
1
a_1
a1,
a
2
a_2
a2,
a
3
⋯
a
n
a_3\cdots a_n
a3⋯an,我们其实可以默认它们全部为非负数,因为对于
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
∣a1∣⋅x1+∣a2∣⋅x2+∣a3∣⋅x3+⋯+∣an∣⋅xn。
那么,又因为在裴蜀定理及其证明中说过裴蜀定理的推广:
对于多个整数
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)
p⋅gcd(∣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);
}