原题:
http://172.16.0.132/senior/#contest/show/1918/2
题目描述:
鸡腿想到了一个很高(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取模就可以了哦!
输入:
一行,输入两个正整数n,k。
输出:
一行,输出一个整数表示答案。
样例输入:
输入1:
3 1
输入2:
100 2
样例输出:
输出1:
4
输出2:
321266186
数据范围限制:
对于30%的数据0
分析:
递推,设f[i][j][k]表示第i行第j列第k个质数有多少个,那我们发现f[i][j][k]=(f[i-1][j][k]+f[i][j-1][k])%2;
边界条件:f[0][i]=0; f[i][0]=分解质因数(i);
其中“分解质因数”代表对i进行分解质因数,例如14,分解后得2^1*7^1,那么f[i][j][1]++,f[i][j][4]++,大家都奇怪为什么是1,和4,不是2和7吧,因为在质数表中,第一个质数是2,第4个质数是7,我们存的是位置,不是数值!!!
最后枚举f[n][k]的每个位置的质数的指数,ans=ans*(f[n][k][i]+1);
实现:
var
ans:int64;
n,k,i,t,j,l:longint;
f:array[0..1001,0..101,0..169]of longint;
lb:array[1..2001]of boolean;
su:array[1..1001]of longint;
procedure gp(n:longint);
var
i,j,k:longint;
begin
k:=0;
fillchar(lb,sizeof(lb),true);
for i:=2 to trunc(sqrt(n)) do
if lb[i] then
for j:=2 to n div i do lb[i*j]:=false;
for i:=2 to n do if lb[i] then
begin
inc(k);
su[k]:=i;
end;
end;
procedure fen(x,y,n:longint);
var
i:longint;
begin
t:=1;
i:=1;
while su[i]<=n do
begin
inc(t);
while n mod su[i] = 0 do
begin
inc(f[x,y,t]);
n:=n div su[i];
end;
inc(i);
end;
end;
begin
gp(1000);
readln(n,k);
for i:=1 to n do fen(i,0,i);
for i:=1 to n do
for j:=1 to k do
for l:=1 to 169 do f[i,j,l]:=(f[i-1,j,l]+f[i,j-1,l]) mod 1000000009;
ans:=1;
for i:=1 to 169 do ans:=(ans*(f[n,k,i]+1)) mod 1000000009;
writeln(ans);
end.