算法 {质数,互质,质因数分解}

算法 {质数,互质,质因数分解}

質數

性质

#质数个数#
[1,N]里面的质数个数 大约是N / ln(N);

@DELI;

常见质数:
[2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71,73,79,83,89,97];

@DELI;

特殊的质数:
2147483647, 9223372036854775807, {1|2}e9+7, {1|2|3}e18+7;

@DELI;

int范围内 相邻两个质数的差值 都是< 300的;

@DELI;

int范围内, 拥有最多的不同质因子个数的是: { 2 , 3 , 5 , 7 , 11 , 13 , 17 , 19 , 23 } \{2, 3,5,7,11,13,17,19,23 \} {2,3,5,7,11,13,17,19,23}她的乘积是 223092870;
int64范围内 是 { 2 , 3 , 5 , 7 , 11 , 13 , 17 , 19 , 23 , 29 , 31 , 37 , 41 , 43 , 47 } \{2, 3,5,7,11,13,17,19,23,29,31,37,41,43,47\} {2,3,5,7,11,13,17,19,23,29,31,37,41,43,47};

代码

線性篩質數 ( O ( N ) O(N) O(N))

namespace ___LinearSieve_Primes{ // 線性篩質數 ($O(N)$)
constexpr int __Range = ?; // 處理的數據範圍是`[2...Range)`;
bool Is_prime[__Range]; // `Is_prime[a]`表示`a`是否為質數;
vector<int> Primes; // [2,3,5,7,...] 表示`[1,...,Range]`裡所有的質數;
int PrimeFactor[__Range]; // `a=PrimeFactor[b]`: `a`为`b`的最大的质因子;

void Initialize(){ // 处理的數據范围為`[1,...,range]`;
    Primes.reserve( __Range);    Primes.clear();
    memset( Is_prime, true, sizeof( Is_prime));  Is_prime[1]=false;
    for( int num = 2; num < __Range; ++num){
        if( Is_prime[ num]){
            Primes.push_back( num);
            PrimeFactor[ num] = num;
        }
        for( int ind = 0;; ++ind){
            int tar = Primes[ ind] * num;  if( tar >= __Range){ break;}
            Is_prime[ tar] = false;
            PrimeFactor[ tar] = PrimeFactor[num]; // 如果是`=Primes[ind]` 則對應為最小質因子;
            //>< `num`的最小的質因子 一定是`>= Primes[ind]`;
            if( num % Primes[ ind] == 0){ // 比如`num`的質因子為`{5,11}`, 那麼此時`Primes[ind] == 5`;
                break;
            }
            //>< 比如`num`的質因子為`{5,11}`, 那麼此時`Primes[ind] == {2/3}`;
        }
    }
}
} // namespace ___LinearSieve_Primes
@TODO: ___LinearSieve_Primes::Initialize();

判断一個數是否为质数 O ( N ) O( \sqrt{N}) O(N )

template< typename _Type> bool ___IsPrime( _Type _a){
    if( _a < 2){ return false;}  
    for( _Type i = 2; i <= _a / i; ++i){ if( _a % i == 0){ return false;}}
    return true;
} // ___IsPrime

错误

质数的无穷性
错误证明: 因为质数的量级可以是无穷的 即 p a p^a pa 其中 a a a是无穷的;
. 这是错误的, 不要凭感觉说质数是无穷的, 因为没准所有的数 的质因数分解 都是某个质数集合里面的数 比如所有数的质因子都是{2,3,5,...,Ma}这个集合里面的;
正确证明: 假如质数是有限的a,b,c,...,z, 则a*b*...*z这个数 同时是a/b/.../z的倍数, 因此(a*b*...*z) + 1这个数 一定不是a/b/.../z的倍数, 因为他是质数;

筆記

@DELIMITER

Property-1
[ 1 , n ] [1,n] [1,n]内的质数个数

The Primes-Count in [ 1 , n ] [1,n] [1,n] is approximately n ln ⁡ n \displaystyle{ \frac{n}{\ln{n} }} lnnn;

@Delimiter

Property-2
0 0 0与任何正数互质

( 0 , x ) (0, x) (0,x) is Co-Prime    ⟺    \iff x ∈ N + x \in N^+ xN+
. Notice, ( 0 , 0 ) (0,0) (0,0) is not Coprime;

Property-3
1 1 1与任何自然数互质

( 1 , x ) (1, x) (1,x) is Co-Prime    ⟺    \iff x ∈ N x \in N xN
. As a lemma, the Euler-Function of 1 1 1 equals to 1 1 1;

@Delimiter

Property-4
( a , b ) (a,b) (a,b)互质的等价代换

( a , b ) (a,b) (a,b) is Co-Prime → \to G C D ( a , b ) = 1 GCD(a,b)=1 GCD(a,b)=1
. As discussed above, ( 1 , 1 ) ( 1 , 0 ) (1,1) (1,0) (1,1)(1,0) is Coprime while ( 0 , 0 ) (0,0) (0,0) is not, the a , b a,b a,b in G C D ( a , b ) GCD(a,b) GCD(a,b) must be N N N and not both 0 0 0;

@Delimiter

Property-5
两数乘积的质因子不变

Let S 1 S1 S1 be the Prime-Factors set of the number a a a, S 2 S2 S2 be the set of b b b; then the Prime-Factors set of a ∗ b a * b ab must be S 1 ∨ S 2 S1 \lor S2 S1S2;
. In other words, any Prime-Factor of a ∗ b a * b ab must be also a Prime-Factor of at least one of a , b a, b a,b;
. As a corollary, every Prime-Factor of n ! n! n! must ≤ n \leq n n, although the number n ! n! n! maybe very large;

@Delimiter

Property-6
合数的最小质因子

If x x x is not a Prime-Number, then m i n ( p i ) ≤ x min(p_i) \leq \sqrt{ x} min(pi)x (in other words, there must exist a Prime-Factors p p p of x x x such that p ∣ x    ∧    p ∈ [ 1 , x ] p | x \ \ \land \ \ p \in [1, \sqrt{x}] px    p[1,x ])
. Example: AcWing-198. 反素数

@Delimiter

Property-7
一个数的质因子个数

+ Let S S S be the multiset of all Prime-Factors of an arbitrary-integer a a a, then the maximal S . s i z e ( ) S.size() S.size() is log ⁡ 2 ( a ) \log_2(a) log2(a) (i.e., S = { 2 , 2 , . . . , 2 } S=\{2,2,...,2\} S={2,2,...,2})
+ Let S S S be the set of all Prime-Factors of an arbitrary-integer a a a, then
. If the type of a a a is int, the maximal S . s i z e ( ) S.size() S.size() is 9 9 9 (i.e., S = { 2 , 3 , 5 , 7 , 11 , 13 , 17 , 19 , 23 } S=\{2, 3,5,7,11,13,17,19,23 \} S={2,3,5,7,11,13,17,19,23} whose product is 223092870; if you proceed multiple the next-prime 29 then it would be 6469693230 which is Out-Of-UINT32_MAX)
. If the type of a a a is long long, the maximal S . s i z e ( ) S.size() S.size() is 15 15 15 (i.e., S = { 2 , 3 , 5 , 7 , 11 , 13 , 17 , 19 , 23 , 29 , 31 , 37 , 41 , 43 , 47 } S=\{2, 3,5,7,11,13,17,19,23,29,31,37,41,43,47\} S={2,3,5,7,11,13,17,19,23,29,31,37,41,43,47} whose product is 614889782588491410; ; if you proceed multiple the next-prime 53 then it would be Out-Of-UINT64_MAX)

互質

定義

#两个数的互质#
對於两个整數a,b 且他俩有GCD(即不同时为0), 如果GCD(a,b) == 1, 則他倆互質;
. 等价定义: a的約數集合與b的約數集合的交集{1};

@DELI;

#若干个数的互质#
對於若干整數Ai 且他们有GCD(即不同时为0), 如果GCD( 所有Ai ) == 1, 则他们互质;

性質

因為GCD(1,1) = 1, 所以1,1互質;
因為GCD(0,1) = 1, 所以0,1互質;

算法

A × B A\times B A×B裡 互質的數對個數

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

N × N N\times N N×N裡互質的數對的個數

@LINK: (https://editor.csdn.net/md/?articleId=126848932)-(@LOC_0);

質因數分解

定義

對於正整數a, 他可以寫成p1^k1 * p2^k2 * ...的性質 其中pi為質數 k1>=1, 即可以用{(p1,k2), (p2,k2), ...}來表示任何正整數;

性質

<= 1e9的数, 其质因子最多有9; (即前10个质数相乘的结果 是大于1e9的);
<= 1e16的数, 其质因子最多有13; (即前14个质数相乘的结果 是大于1e16的);
<= 9e18的数, 其质因子最多有15; (即前16个质数相乘的结果 是大于9e18的);

@DELI;

#1的質因數分解為#
比如12的質因數分解為{(2,2), (3,1)}; 而1的質因數分解為{}, 不要把它形成是{(2,0)} 這樣的話 一個數的質因數分解就不唯一了;
因此, #任意數的質因數分解 都是唯一確定的#;

@DELI;

一個數a的質因數分解p1^k1 * p2^k2 * ... * pn^kn;
. k1+k2+...的最大值為 log ⁡ 2 ( a ) \log_2(a) log2(a), 即二次冪 2*2*...*2這個數;
. n的最大值 (即不同質因子的個數), 對於int9 對應2 * 3 * 5 * 7 * 11 * 13 * 17 * 19 * 23這個數; 對於int64 他是15 對應2 * 3,5,7,11,13,17,19,23,29,31,37,41,43,47這個數;

算法

求一個數的质因数分解

O ( a ) O(\sqrt{a}) O(a )(暴力)
{ // 一個數的质因数分解 ($O(\sqrt{a})$)
    auto ___a = ?;
    map< decltype(___a), int> ___Factors; // `a`的質因數分解
    for( int ___p = 2; ___p <= ___a / ___p; ++___p){
        if( ___a % ___p == 0){
            int ___k = 0;
            while( ___a % ___p == 0){
                ++ ___k;
                ___a /= ___p;
            }
            ___Factors[ ___p] = ___k;
        }
    }
    if( ___a > 1){
        ___Factors[ ___a] = 1;
    }
} // 一個數的质因数分解 ($O(\sqrt{a})$)
O ( 1 ) O(1) O(1)(预处理)
性質

求a的質因數分解, 需要提前對[1,a]裡面的所有數 (線性篩質數可以)預處理出Ma(x)表示x的最大/最小質因子;

代碼
{ // 一個數的质因数分解 ($O(1)$)
    int ___a = ?;
    for( int ___t = ___a; ___t > 1;){
        int ___p = ___LinearSieve_Primes::PrimeFactor[ ___t];
        int ___k = 0;
        while( ___p == ___LinearSieve_Primes::PrimeFactor[ ___t]){
            ___t /= ___p;
            ++ ___k;
        }
		// `___p ^ ___`k;
    }
} // 一個數的质因数分解 ($O(1)$)
O ( a ln ⁡ a ) O( \frac{\sqrt{a}}{ \ln{ \sqrt{a}}}) O(lna a )(预处理)
性質

實際時間 要更小, 因為這個for循環 大概率不會遍歷所有的[1, sqrt(a)]裡面的質數, 因為___t是在不斷的變小的;

代碼
{ // 一個數的质因数分解 ($O( \frac{\sqrt{a}}{ \ln{ \sqrt{a}}})$)
    auto ___a = ?;
    map< decltype(___a), int> ___Factors; // `a`的質因數分解
    auto ___t = ___a;
    for( 滿足`___p <= ___t / ___p`的所有*質數*){
        int ___k = 0;
        while( ___t % ___p == 0){
            ___t /= ___p;
            ++ ___k;
        }
		___Factors[ ___p] = ___k;
    }
    if( ___t > 1){
		___Factors[ ___t] = 1;
    }
} // 一個數的质因数分解 ($O( \frac{\sqrt{a}}{ \ln{ \sqrt{a}}})$)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值