质因数分解(N, N!, 大数) 及 唯一分解定理

【唯一分解定理】

又称为 算术基本定理

定义:

任何一个大于1的自然数 ,如果 N N N不为质数,都可以唯一分解成有限个质数的乘积 N = P 1 a 1 P 2 a 2 . . .   P n a n N=P_1^{a_1}P_2^{a_2}...\,P_n^{a_n} N=P1a1P2a2...Pnan,这里 P 1 < P 2 < . . .   < P n P1\lt P_2\lt...\,\lt P_n P1<P2<...<Pn均为质数,其诸指数 a i a_i ai正整数

这样的分解称为 N N N标准分解式

应用:
  1. N N N正因数个数 σ 0 ( N ) = ( 1 + a 1 ) ( 1 + a 2 ) . . . ( 1 + a n ) \sigma_0(N)=(1+a_1)(1+a_2)...(1+a_n) σ0(N)=(1+a1)(1+a2)...(1+an),其中 a i a_i ai N N N标准分解中各质数的指数

  2. N N N全体正因数之和 σ 1 ( N ) = ( 1 + P 1 + P 1 2 + . . .   + P 1 a 1 ) ( 1 + P 2 + P 2 2 + . . .   + P 2 a 2 ) . . .   ( 1 + P n + P n 2 + . . .   + P n a n ) \sigma_1(N)=(1+P_1+P_1^2+...\,+P_1^{a_1})(1+P_2+P_2^2+...\,+P_2^{a_2})...\,(1+P_n+P_n^2+...\,+P_n^{a_n}) σ1(N)=(1+P1+P12+...+P1a1)(1+P2+P22+...+P2a2)...(1+Pn+Pn2+...+Pnan)

    结合等比数列求和公式,可推得: σ 1 ( N ) = 1 − P 1 a 1 + 1 1 − P 1 ⋅ 1 − P 2 a 2 + 1 1 − P 2 ⋅ . . .   ⋅ 1 − P n a n + 1 1 − P n \sigma_1(N)=\frac{1-P_1^{a_1+1}}{1-P_1}\cdot\frac{1-P_2^{a_2+1}}{1-P_2}\cdot...\,\cdot\frac{1-P_n^{a_n+1}}{1-P_n} σ1(N)=1P11P1a1+11P21P2a2+1...1Pn1Pnan+1

  3. 对于:
    a = p 1 a 1 ⋅ p 2 a 2 ⋅ p 3 a 3 ⋯ p n a n a=p_1^{a_1}\cdot p_2^{a_2}\cdot p_3^{a_3} \cdots p_n^{a_n} a=p1a1p2a2p3a3pnan

    b = p 1 b 1 ⋅ p 2 b 2 ⋅ p 3 b 3 ⋯ p n b n b=p_1^{b_1}\cdot p_2^{b_2}\cdot p_3^{b_3} \cdots p_n^{b_n} b=p1b1p2b2p3b3pnbn

有:
gcd ⁡ ( a , b ) = p 1 min ⁡ ( a 1 , b 1 ) ⋅ p 2 min ⁡ ( a 2 , b 2 ) ⋅ p 3 min ⁡ ( a 3 , b 3 ) ⋯ p n min ⁡ ( a n , b n ) \gcd(a,b)=p_1^{\min(a_1,b_1)}\cdot p_2^{\min(a_2,b_2)}\cdot p_3^{\min(a_3,b_3)}\cdots p_n^{\min(a_n,b_n)} gcd(a,b)=p1min(a1,b1)p2min(a2,b2)p3min(a3,b3)pnmin(an,bn)
l c m ( a , b ) = p 1 max ⁡ ( a 1 , b 1 ) ⋅ p 2 max ⁡ ( a 2 , b 2 ) ⋅ p 3 max ⁡ ( a 3 , b 3 ) ⋯ p n max ⁡ ( a n , b n ) lcm(a,b)=p_1^{\max(a_1,b_1)}\cdot p_2^{\max(a_2,b_2)}\cdot p_3^{\max(a_3,b_3)}\cdots p_n^{\max(a_n,b_n)} lcm(a,b)=p1max(a1,b1)p2max(a2,b2)p3max(a3,b3)pnmax(an,bn)


【质因数分解】


定义:

每个合数都可以写成几个质数相乘的形式,其中每个质数都是这个合数的因数,把一个合数用质因数相乘的形式表示出来,实际上就是 得到 N N N的标准分解式

模板:
①对 N N N进行分解

先得到素数表,然后遍历拆分即可。对于 N N N,只需要得到 1 1 1~ N \sqrt N N 的素数表即可,即 m a x n = N maxn=\sqrt N maxn=N

int prime[maxn],tot;
bool vis[maxn];
void get_prime()       //欧拉筛得到素数表
{
    memset(vis,0,sizeof(vis));
    tot=0;
    for(int i=2;i<=maxn;i++)
    {
        if(!vis[i])
            prime[++tot]=i;
        for(int j=1;j<=tot&&i*prime[j]<=maxn;j++)
        {
            vis[i*prime[j]]=true;
            if(i%prime[j]==0)
                break;
        }
    }
}
int p[maxn],a[maxn],cnt;
void get_prime_factor(int n)
{
    cnt=0;
    for(int i=1;prime[i]*prime[i]<=n;i++)
    {
        if(n%prime[i]==0)
        {
            cnt++;
            p[cnt]=prime[i];    //质因数
            a[cnt]=0;           //对应指数
            while(n%prime[i]==0)
            {
                a[cnt]++;       //统计个数
                n/=prime[i];
            }
        }
        if(n==1)
        	break;
    }
    if(n>1)   //不要漏了这句
    {
        cnt++;
        p[cnt]=n;
        a[cnt]=1;
    }
}

②对 N ! N! N!进行分解

很明显,对于 n ! n! n!,其质因数肯定 包括 1 1 1~ n n n的所有质数,只是各质数的个数(指数)尚不确定(至少为 1 1 1)。

8 ! 8! 8! 1 × 2 × 3 × 4 × 5 × 6 × 7 × 8 1\times2\times3\times4\times5\times6\times7\times8 1×2×3×4×5×6×7×8,以质因数 2 2 2为例

其中 2 2 2的倍数: 2 , 4 , 6 , 8 2,4,6,8 2,4,6,8,共 4 4 4
其中 4 4 4的倍数: 4 , 8 4,8 4,8,共 2 2 2
其中 8 8 8的倍数: 8 8 8,共 1 1 1

参考blog:https://www.cnblogs.com/Slager-Z/p/7780382.html

所以质因数 2 2 2在分解式中的指数为 4 + 2 + 1 = 7 4+2+1=7 4+2+1=7个,这样就可以有效避免重复统计。

c n t ( 2 ) = 8 / 2 + 8 / 2 / 2 + 8 / 2 / 2 / 2 cnt(2)=8/2+8/2/2+8/2/2/2 cnt(2)=8/2+8/2/2+8/2/2/2,这个计算过程可以很简单地用递归实现:

int cal(int n,int p)     //计算n!中质因数p的个数(指数)
{
    if(n==0)
        return 0;
    return cal(n/p,p)+n/p;
}

完整代码:

int prime[maxn],tot;
bool vis[maxn];
void get_prime()       //欧拉筛得到素数表
{
    memset(vis,0,sizeof(vis));
    tot=0;
    for(int i=2;i<=maxn;i++)
    {
        if(!vis[i])
            prime[++tot]=i;
        for(int j=1;j<=tot&&i*prime[j]<=maxn;j++)
        {
            vis[i*prime[j]]=true;
            if(i%prime[j]==0)
                break;
        }
    }
}
int cal(int n,int p)  //计算n!中质因数p的个数(指数)
{
    if(n==0)
        return 0;
    return cal(n/p,p)+n/p;
}
int p[maxn],a[maxn];
void get_prime_factor(int n)
{
    for(int i=1;prime[i]<=n;i++)
    {
        p[i]=prime[i];
        a[i]=cal(n,prime[i]);
    }
}

③Pollard-rho 大数因式分解

待补充…

你可能感兴趣的:(★Tips,★数学,#,【数论】)