快速求出n!的質因數的個數


一般做組合數的題目都要進行質因數的分解,我們一般是for循環對每個數進行質因數分解,大多數情況都不會超時,但極少數的情況下,題目會不允許這樣的做法,所以我們需要學會一種更快的方法來求質因數。

我們一般的方法是對每個數進行質因數分解:

 

inline void calc(int x,int val)
{
    int xx=x;
    for(int i=2;i*i<=xx;i++)
    {
        while(x%i==0)//不斷進行除法,找出多少的當前的質數
        {
            c[i]+=val;x/=i;
        }
        if(x==1)break;
    }
    if(x>1)c[x]+=val;//如果剩下的數也是個質數,那么這個質數也要加上val
}

 

但如果想要更快的分解,我們可以直接對n!進行分解:

首先先進行素數篩選,得出素數表

然后進行如下操作:

 

1 inline long long calc(int n,int x)//x表示想要求的質數,函數的作用是求出x的個數,n表示要求的n!(例:n=8表示8!)
2 {   long long cnt=0;
3     for(long long i=x;i<=n;i*=x)//為了防止i的溢出,所以我們要開long long
4       {cnt+=n/i;    
5             } 
6     return cnt;
7     }   

 

我們來一個樣例說明一下:

1  2  3  4  5  6  7  8         我們求得在8!中2的個數

     1      1      1      1         首先我們先計算出2的倍數的個數:8/2=4

            1              1         其次我們計算出4的倍數的個數:    8/4=2(上面一個式子求出了第一層,現在求第二層)

                            1         最后我們解出第三層的2的個數:    8/8=1

我們把4+2+1=7,所以一共7個2出現了。

 即:cnt(x)=[n/(x^1)]+[n/(x^2)]+[n/(x^3)]+...(直到x的次方大於n)

到這里我們可以發現:我們平時求的方法是一列一列求的(就是每一個數算一遍),而這個方法我們每一行每一行的求,雖然效果一樣,但求起來速度很快。值得學習。

故做法:

  1.先把素數表打好

  2.for循環把小於n的每個質數進行一次運算,用數組記錄

  3.結束

非常快。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM