数论之因子个数的求法

数论之因子个数的求法

1. N的因子个数

条件:给定任意一个一个正整数N

要求:求其因子的个数

首先给出结论:对于任意的整型N,分解质因数得到N= P1^x1 * P2^x2* …… * Pn^xn;

则N的因子个数M为 M=(x1+1) * (x2+1) * …… *(xn+1);

证明过程:

首先 举个例子吧

24 = 2^3 * 3^1;

其质因子有:为2和3  指数为 3和1

那么对于2 有0 1 2 3四种指数选择,对于3 有0 1两种指数选择

所以 就是4 * 2 = 8 个因子个数

如果还是不懂,那么我们就列举出来吧

2    3

2^0*3^0=1            2^0*3^1=3

2^1*3^0=2            2^1*3^1=6

2^2*3^0=4            2^2*3^1=12

2^3*3^0=8            2^3*3^1=24

结果很清晰了吧??其实这里用到了数学的排列组合的知识

也就是说每一个质因子的不同指数幂与其它质因子相乘,得到的结果一定不会重复

因此能够将所有的因子都列举出来。

所以N的因子数M,我们可以用M=(x1+1) * (x2+1) * …… *(xn+1)表示

 代码:

/*

 *

 *   N的因子个数

*/

#include<iostream>

using namespace std;

 

int main()

{

   int N, count = 1, dis = 2, ans = 1;

   cin >> N;   //Input thenumber of N

   while( N != 1 )

    {

       while( N % dis == 0 )   //"dis" into the circle must be a prime

       {

           N /= dis;

           count++;

       }

       ans *= count;

       count = 1;

       dis++;

    }

   cout<< ans <<endl;

   return 0;

}

2. N!的因子个数

有上面的结论,这个问题就变得明朗多了吧?嘿嘿,不要着急,这里面还有许多细节问题需要我们考虑。

a.  最大的质因子一定不会大于N

b.  N的质因子并不完全包含N!所有的质因子

至于原因是什么,自己想想吧,嘿嘿

 

那我们就直接说思路了:

首先,我们可以把所有的N以内的质数给打表求出来

然后,求每一个质因子的指数个数,这里用到了一个公式,:

ei = [N/pi^1] +  [N/pi^2] + …… + [N/pi^n]  其中[]为取整

附:这一步最近又想到了一个更好的方法 

int ei=0;

while(N) 

    ei+=(N/=pi);

怎么样??

(想一想为什么,实在想不通你就举个例子试一下)

最后,就是套公式计算了,M=(e1+1)*(e2+1)*……*(en+1)

还是举个例子吧

比如5!

质因子2的指数是 2+1=3;

质因子3的指数是 1;

质因子5的指数是 1;

所以因子个数为 4 * 2 * 2= 16

5!=120 因子有1 2 3 4 5 6 810 12 15 20 24 30 40 60 120  刚好16个

 代码:

/*

  *   N!的因子个数

 */

#include<iostream>

using namespace std;

int prime[1005], num = 0;// "num"is the prime

bool m[10005] = { 1, 1, 0};

void SetTable(int x) // sieve

{

   for( int i = 2; i <= x; i++ )

       if(!m[i])

       {

           prime[num++] = i;

           for( int j = i+i ; j <= x; j += i)

                m[j] = true;

       }

}

int GetEi(int n ,int x)

{

   int ans = 0;

   while(n)

       ans += (n/=x);

   return ans+1;

}

 

int main()

{

   int N, ans = 1;

   cin >> N;   //Input thenumber of N

   SetTable(N);

    for(int  i = 0; i < num; i++ )

       ans *= GetEi(N, prime[i]);

   cout<< ans <<endl;

   return 0;

}

3.给定数列的乘积因子个数

其实这个也是基于第一个结论得到的。

给定 a1 a2 a3 …… an;

我们可以找到最大的一个元素Max(a);

把Max以内的素数打表

然后把质因子清零,进行如下循环,就可以找到各个质因子的个数:

for(a=1;a<=n;a++)

 

   for(p=1;p<_;p++ )

 

       if(__)

            e(p)++;

这样质因子的质数个数就求出来了,然后就可以根据公式M=(e1+1)*(e2+1)*……*(en+1)求出因子个数

代码:

/*

*   给定数列乘积的因子个数

*/

#include<cstdio>

#include<iostream>

using namespace std;

 

int prime[1005], num = 0;// "num"is the prime

bool m[10005] = { 1, 1, 0};

void SetTable(int x) // sieve

{

   for( int i = 2; i <= x; i++ )

       if(!m[i])

       {

           prime[num++] = i;

           for( int j = i+i ; j <= x; j += i)

                m[j] = true;

       }

}

 

int main()

{

   int N, n[100], Max = -1;

   cin >> N;   //Input thenumber of N

   for(int i = 1; i <= N; i++ ){

       cin >> n[i];

       if( n[i] > Max )

           Max = n[i];

    }

   SetTable(Max);

   int ans = 0;

   for( int  i = 0; i < num; i++ )

       for( int j = 1; j <= N; j++ )

           while( n[j]%prime[i] == 0 )

           {

                ans ++;

                n[j] /= prime[i];

           }

   cout<< ans <<endl;

   return 0;

}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值