色婷婷狠狠18禁久久YY,CHINESE性内射高清国产,国产女人18毛片水真多1,国产AV在线观看

legendre第一定理

劉柏宏2年前14瀏覽0評論

legendre第一定理?

Legendre定理:

設n為一個正整數,那么在n!的標準素因子分解式中,素數p的最高次項為L_{p}(n!),則

L_{p}(n!)=\sum_{k\geq1} \left [ \frac{n}{p^k} \right ]

當模數不為素數,且不方便使用CRT進行合并時,可以考慮對組合數分解質因數,由于組合數可以寫為一個階乘除以兩個階乘的形式,可以對這三個階乘分別分解質因數,然后使用指數的減法,得到最后組合數的標準分解。

證明我就不在這里細說了,反正這個定理可以讓我們快速求出p的指數。

下面是例題。

題目描述:

求方程x_{1}+x_2+......x_k=n的非負整數解的組數n,k≤100,000,答案對20080814取模輸入:

僅一行,包含兩個正整數n,k。

輸出:一個整數,表示方程不同解的個數,這個數可能很大,你只需輸出mod 20080814 的結果。

樣例輸入:

1 1

樣例輸出:

1

思路分析:

利用隔板法,答案為\LARGE C_{n+1}^{k-1}

由于20080814=2*13*772339(3個均為質因數),故可以用CRT。

也可以用Legendre定理分解階乘的質因數。

但是此題的輸入有坑,n,k需要特殊處理,詳見代碼。

代碼實現:

#include<cstdio>

#include<iostream>

#include<cstring>

using namespace std;

#define ll long long

ll n,m,p[200005],w[200005],k,ans=1;

bool v[200005];

ll olsf()//歐拉篩法求素數

{for(ll i=2;i<=n+1;i++) { if(!v[i])

{ k++; p[k]=i; v[i] = 1; }

for(ll j=1;j<=k&&p[j]*i<=n+1;j++)

{ v[i*p[j]]=1;if(i%p[j]==0)

break; }

}

}

ll qkpow(ll x,ll y)//快速冪不解釋

{

ll ans=1;

while(y)

{

if(y&1)

ans=(ans*x)%20080814;

x=(x*x)%20080814;

y/=2;

}

return ans%20080814;

}

int main()

{

scanf("%lld%lld",&m,&n);

n=n+m-1;

m--;

olsf();

for(ll i=1;i<=k;i++)//求分子的分解

for(ll j=p[i];j<=n;j*=p[i])

w[i]+=n/j;

for(ll i=1;i<=k;i++)//求分母的分解

for(ll j=p[i];j<=m;j*=p[i])

w[i]-=m/j;

for(ll i=1;i<=k;i++)

for(ll j=p[i];j<=n-m;j*=p[i])

w[i]-=(n-m)/j;

for(ll i=1;i<=k;i++)

ans=(ans*qkpow(p[i],w[i]))%20080814;

printf("%lld",ans);

歐拉篩java,legendre第一定理