题目描述
定义一个新的运算符!!!,给了如下的定义:
1、n!k=n!(k−1)∗(n−1)!k(n>0andk>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)
现在告诉你 nnn 和 kkk 你能告诉他 n!kn!kn!k 的不同约数个数有多少个吗?只要对 1e9+91e^9+91e9+9 取模就可以了哦!
题目解析
设fi,jf_{i,j}fi,j为 i!ji!ji!j ,根据定义可以得出 fi,j=fi−1,j×fi,j−1f_{i,j}=f_{i-1,j}\times f_{i,j-1}fi,j=fi−1,j×fi,j−1。
因为求的是约数个数可以把 fi,jf_{i,j}fi,j分解质因数,为加一个第KKK个质数的个数,因为是乘法,所以质数的个数相加即可。
处理边界条件:fi,1=f_{i,1}=fi,1=分解质因数(i!)(i!)(i!)
最后枚举fn,kf_{n,k}fn,k的每个位置的质数的指数,ans=ans×(fn,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;
}