Description
鸡腿想到了一个很高(sha)明(bi)的运算符,那就是’!’,没错就是感叹号。他给了如下的定义:
1、n!k = n!(k-1) * (n-1)!k (n> 0 and k > 0)
2、n!k = 1 (n = 0)
3、n!k = n (k = 0)
现在鸡腿告诉你n和k你能告诉他n!k的不同约数个数有多少个吗?只要对1,000,000,009取模就可以了哦!
Input
一行,输入两个正整数n,k。
Output
一行,输出一个整数表示答案。
Sample Input
输入1:
3 1
输入2:
100 2
Sample Output
输出1:
4
输出2:
321266186
Data Constraint
对于30%的数据0 <n ≤ 10, 0 <k ≤ 10;
对于100%的数据0 <n ≤ 1000, 0 <k ≤ 100。
//written by zzy
题目大意:
n!k = n!(k-1) * (n-1)!k (n> 0 and k > 0)
n!k = 1 (n = 0)
n!k = n (k = 0)
求自定义函数n!k的约数个数Mod 1e9+9
解法:
用暴力预处理出前n!k(5*5) 的结果,如下图所示:
0 |1 2 3 4 5 (n)
——————
1 |1 1 1 1 1
2 |2 2 2 2 2
3 |6 12 24 48 96
4 |24 288 6912 331776 31850496
5 |120 34560 238878720 79254226206720 (爆了无法显示)
( k)
设d[i][j]为 i!j 的结果,不难发现
d[i][1]=i!; d[i][j]=d[i-1][j]*d[i][j-1];
那么既然求d[n][k]的约数个数,不难想到分解质因数
先在1…n中做一次线性筛
设f[i][j][p]表示 将d[i][j]分解质因数后第k位质数的幂
不难想到
f[i][1][p]=|i/p|+|i/pi2|+…+|i/pk|(pk<=i)(详见上一片博客)
f[i][j][p]=f[i-1][j][p]+f[i][j-1][p]
最后答案为 ans ×=f[n][k][1…pmax];
#include<bits/stdc++.h>
#define N 1005
#define M 105
#define K 170
#define Mod 1000000009
using namespace std;
int i,j,l,n,m,k;
int p[K];
int f[N][M][K];
bool b[N];
long long ans;
long long get(int n,int p)
{
long long s=0;
int x=p;
while (x<=n) {
s+=n/x; x*=p;
}
return s;
}
int main()
{
scanf("%d%d",&n,&m);
memset(b,true,sizeof(b));
for (i=2;i<=n;i++){
if (b[i]) {
for (j=1;j<=n/i;j++) b[i*j]=false;
l++; p[l]=i;
}
}
for (i=1;i<=n;i++)
{
for (k=1;k<=l;k++) f[i][1][k]=get(i,p[k]);
for (j=2;j<=m;j++)
{
for (k=1;k<=l;k++)
f[i][j][k]=(f[i-1][j][k]+f[i][j-1][k])%Mod;//不模会爆,作为乘数模后无影响
}
}
ans=1;
for (k=1;k<=l;k++)
ans=(ans*(f[n][m][k]+1))%Mod;
printf("%lld",ans);
}