一般情况下我们可以迭代 g = _gcd(g,a[i]) (0<i<n, g = a[0]),来获得n个数的最大公约数。
但数论中还有另一种已经证明的办法(转载)
求多个数的最大公约数采用反复用最小数模其它数的方法,即对其他数用最小数多次去减,直到剩下比最小数更小的余数。令n个正整数为a1,a2,…,an,求多个数最大共约数的算法描述为:
(1) 找到a1,a2,…,an中的最小非零项aj,若有多个最小非零项则任取一个
(2) aj以外的所有其他非0项ak用ak mod aj代替;若没有除aj以外的其他非0项,则转到(4)
(3) 转到(1)
(4) a1,a2,…,an的最大公约数为aj,结束算法
于是写下本蒟蒻的代码试了试。
优先队列Version
n = 3e5 时,T = 400ms
void Get_gcd()
{
priority_queue<ll,vector<ll>,greater <ll> > q;
for (int i = 1; i < n; ++i)
{
q.push(x[i] - x[i-1]);
}
ll mx_gcd = 1; //最大公约数
while