算法 {最大公约数GCD}

算法 {最大公约数GCD}

最大公约数GCD

定義

#最大公約數/Greatest Common Divisor/GCD#
若干個整數 A i Ai Ai(不能全为0), 找到最大的整数 T > 0 T>0 T>0 滿足: ∀ a ∈ A i , a % T = 0 \forall a \in Ai, a\%T =0 aAi,a%T=0;
. 比如{-6,0,4}的GCD為2;
等價定義: 所有Ai的約數集合的交集 中的最大值, 為GCD;

性質

#從質因數分解角度去看GCD;#
a = p1^k1 * p2^k2 * p3^k3 * ..., b = p1^kk1 * p2^kk2 * p3^kk3 * ..., c = p1^kkk1 * p2^kkk2 * p3^kkk3 * ...;
那麼 p1^min(k1,kk1,kkk1) * p2^min(k2,kk2,kkk2) * p3^min(k3,kk3,kkk3) * ... 就是a,b,c的GCD;

@DELI;

#GCD的除法#
已知GCD(a,b) == c; 對於c的任意的約數d, 則有GCD(a/d, b/d) == c/d;
. 證明: 可以藉助上一條性質, 令d = p1^K1 * p2^K2 * ..., 那麼因為k1/kk1/kkk1 >= K1, 整除除法 在質因數分解的角度 就是做指數的減法, 即c/d等於 讓c的各個指數減去K1,K2,..., 又因為min(k1-K1, kk1-K1, kkk1-K1) == min(k1,kk1,kkk1)-K1;

算法

若干个數的GCD (质因数分解)

代码
GCD( vector< map<int,int> > _v){ // `v`为所有数的质因数分解;
	map<int,int> ANS; // 答案的质因数分解
	for( p : 同时出现在`v[0|1|...]`里的质因子){
		ANS[p] = min( {v[0|1|...][p]}); // 取最小*幂次方*;
	}
	return ANS;
}
性质

质因数分解的角度 (就和二进制运算时的拆位一样), 单独研究某一个质因子p, 取最小幂次方m, 那么他在答案里 就是p^m;

若干个數的GCD ( l o g N logN logN取模)

代码
template< class _Type_> _Type_ ___GCD( _Type_ const* _arr, int _len){ // 返回值一定`>0`;
    ASSERT_SYSTEM_( _len > 0);
    auto gcd = []( _Type_ _a, _Type_ _b){ ASSERT_SYSTEM_( (_a==0 && _b==0)==0); while( _b != 0){ _a %= _b; {auto t=_a; _a=_b; _b=t;}} return (_a<0 ? (-_a):_a);};
    _Type_ ANS = _arr[0];
    for( int i = 1; i < _len; ++i){ ANS = gcd( ANS, _arr[i]);}
    return ANS;
} // ___GCD
性質

樸素的GCD算法 是直接返回_a, 而不是abs(_a) 這是我們自己的規定;
這很重要 比如在拓展GCD算法裡, 當if( b == 0)時, 此時GCD是abs(a), 因此如果你直接返回{1,0} 這是錯誤的, 比如a=-2, 顯然-2 * 1 != 2, 因此要特判;

GCD==?的數對個數

N × N N \times N N×NGCD==質數的數對個數

@LINK: (https://editor.csdn.net/md/?not_checkout=1&articleId=126848932)-(@LOC_1);

A × B A\times B A×BGCD==x的數對個數

@LINK: https://editor.csdn.net/md/?not_checkout=1&articleId=130248080;

[ L 1 , R 1 ] × [ L 2 , R 2 ] [L1,R1] \times [L2,R2] [L1,R1]×[L2,R2]GCD==x的數對個數

模板題: @LINK: https://www.acwing.com/problem/content/2704/;
利用二維前綴和的思想, 令F(A,B): A*B裡 GCD==x的數對個數(這是個算法模板), 那麼答案為F(R1, R2) - F(L1-1, R2) - F(L2, R1-1) - F(L1-1, L2-1);

例题

https://editor.csdn.net/md/?not_checkout=1&articleId=130320865

筆記

对两数AB的GCD, (规定两者都是自然数, 且不同时为 0 0 0)

假设AB的所有公约数集合是S, 做法是: 找到另外两个数CD, 其公约数集合也等于S;
… 公约数集合相同, 自然最大公约数也相同;

令A >= B, A = Ka * G, B = Kb * G (G为AB的GCD, Ka与Kb互质)

令C = A % B, 即: C = (Ka % Kb) * G

根据: 取模数, 可知: C与Kb一定互质, 但与Ka不一定互质;

即, (A, B的GCD)为G, 而(B, C的GCD)也为G;

故求(A, B)的GCD, 且A>=B, 等价于求(B, A%B)的GCD
因为要保证第一参数>=第二参数, 所以要写成(B, A%B), 而不是(A%B, B)


比如, 求(10, 6)的GCD

(10, 6) -> (6, 4) -> (4, 2) -> (2, 0)

每次取模, 相当于取半, 所以时间是Log2(N);
递归的终结是: 第二参数为0

@DELI;

Property-1
x x x 的约数个数

A = p 1 a 1 ∗ p 2 a 2 ∗ . . . A = p_1^{a_1} * p_2^{a_2} * ... A=p1a1p2a2..., then the number of divisors of A A A equals ( 1 + a 1 ) ∗ ( 1 + a 2 ) ∗ . . . (1 + a_1) * (1 + a_2) * ... (1+a1)(1+a2)...;

Proof:
. For any divisor a a a of A A A, every Prime-Factor of a a a must be also a Prime-Factor of A A A;
. Therefore, for every item p i a i p_i^{a_i} piai, there are a 1 + 1 a_1 + 1 a1+1 choices: p i 0 , p i 1 , p i 2 , . . . p_i^0, p_i^1, p_i^2, ... pi0,pi1,pi2,...;

@Delimter;

Property-2
a ∈ i n t a \in int aint 的最大约数个数

The Maximal-Divisor-Count in the range int [ 1 , 2147483647 ] [1, 2147483647] [1,2147483647] is 1536 1536 1536;
. Two numbers a = 1745944200 / 2113511400 a = 1745944200/2113511400 a=1745944200/2113511400 attains this peak: 2 3 ∗ 3 3 ∗ 5 2 ∗ 7 ∗ 11 ∗ 13 ∗ 17 ∗ ( 19 / 23 ) 2^3 * 3^3 * 5^2 * 7 * 11 * 13 * 17 * (19/23) 2333527111317(19/23);

  • 35
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值