题目描述
定义一个新的运算符 ! ! !,给了如下的定义:
1
、
n
!
k
=
n
!
(
k
−
1
)
∗
(
n
−
1
)
!
k
(
n
>
0
a
n
d
k
>
0
)
1、n!k = n!(k-1) * (n-1)!k (n> 0 and k > 0)
1、n!k=n!(k−1)∗(n−1)!k(n>0andk>0)
2
、
n
!
k
=
1
(
n
=
0
)
2、n!k = 1 (n = 0)
2、n!k=1(n=0)
3
、
n
!
k
=
n
(
k
=
0
)
3、n!k = n (k = 0)
3、n!k=n(k=0)
现在告诉你 n n n 和 k k k 你能告诉他 n ! k n!k n!k 的不同约数个数有多少个吗?只要对 1 e 9 + 9 1e^9+9 1e9+9 取模就可以了哦!
题目解析
设 f i , j f_{i,j} fi,j为 i ! j i!j i!j ,根据定义可以得出 f i , j = f i − 1 , j × f i , j − 1 f_{i,j}=f_{i-1,j}\times f_{i,j-1} fi,j=fi−1,j×fi,j−1。
因为求的是约数个数可以把 f i , j f_{i,j} fi,j分解质因数,为加一个第 K K K个质数的个数,因为是乘法,所以质数的个数相加即可。
处理边界条件: f i , 1 = f_{i,1}= fi,1=分解质因数 ( i ! ) (i!) (i!)
最后枚举 f n , k f_{n,k} fn,k的每个位置的质数的指数, a n s = a n s × ( f n , k , i + 1 ) ans=ans\times (f_{n,k,i}+1) ans=ans×(fn,k,i+1)
代码
#include<bits/stdc++.h>
#define ll long long
#define M 1000000009
using namespace std;
ll n,k,cnt,ans=1;
int f[1005][105][205],prime[205];
bool vis[1005];
ll cal(ll n,ll p)
{
if(n<p) return 0;
return n/p+cal(n/p,p);
}
int main()
{
for(int i=2;i<=1000;i++)
if(!vis[i])
{
prime[++cnt]=i;
for(int j=i+i;j<=1000;j+=i)
vis[j]=1;
}
cin>>n>>k;
for(int i=1;i<=n;i++)
for(int j=1;j<=cnt;j++)
f[i][1][j]=cal(i,prime[j])%M;
for(int i=2;i<=n;i++)
for(int j=2;j<=k;j++)
for(int l=1;l<=cnt;l++)
f[i][j][l]=(ll)(f[i-1][j][l]+f[i][j-1][l])%M;
for(int i=1;i<=cnt;i++)
(ans*=(ll)(f[n][k][i]+1)%M)%=M;
cout<<ans;
return 0;
}