###Description
###Input
一行由空格隔开的两个整数,分别是 n 和 m。
###Output
一行表示答案。
###Sample Input
Input1:
6 1
Input2:
6 3
###Sample Output
Output1:
10
Output2:
2248
###Data Constraint
###Hint
第一个样例中,合法的方案有 (1, 1),(1, 2),(1, 3),(1, 6),(2, 1),(2, 2),(2, 3),(3, 1),(3, 2),(6, 1) 共 10 种。
###题解
一看题,艾玛,一道神仙题。心凉了一大截。
还是无脑地上暴力吧。最后爆0。往事不堪回首
咳咳,直接讲正解。
题意:要求找出m*2个数的集合满足集合中的每个数可以整除n且集合中每个数的乘积小于n^m的方案。
然后,直接求不好求。
我们发掘一下一些神奇的性质。
我们设
A表示集合小于n^m的方案
B表示集合等于n^m的方案
C表示集合大于n^m的方案
那么对于一个{x 1,x 2,x 3,……,x m2}令乘积小于n^m
那么就把这个集合反一下:
{n/x 1,n/x 2,n/x 3,……,n/x m2}
那么它的乘积大于n^m
于是可以发现,一个集合乘积小于nm,必然对应一个集合乘积大于nm
那么,显而易见地发现:A=C
因为,A+B+C=yueshuhe(n)^(2m)
那么,A=(yueshuhe(n)^(2m)-B)/2
这条式子比较优美了。
那么我们就可以求满足集合乘积=n^m的方案就得到答案。
我们分解n=p[i]^q[i]
那么对于每个数的质因数中,他们的和等于q[i]*m
这就是一个背包问题嘛。
先枚举当前到第l个质因数
设f[i,j]表示当前到集合中的第i个数,它分解质因数中质因数为第l个的指数的和为j的方案数。
直接转移即可。
顺利解决问题。
###代码
uses math;
var
i,j,k,l,n,m,u,x,y:longint;
ans,ano,mo:int64;
a:array[1..10000,1..6] of longint;
bz:array[1..1000000] of boolean;
p,q,op:array[0..100000] of longint;
now:array[1..6] of longint;
f:array[0..10000,0..3000] of int64;
function ksm(a,b:int64):int64;
var
t,y:int64;
begin
t:=1;
y:=a;
while b<>0 do
begin
if(b and 1)=1 then
t:=(t*y) mod mo;
y:=(y*y) mod mo;
b:=b shr 1;
end;
exit(t);
end;
begin
assign(input,'count.in');reset(input);
assign(output,'count.out');rewrite(output);
mo:=998244353;
readln(n,m);
for i:=2 to 1000000 do
begin
if not bz[i] then
begin
inc(op[0]);
op[op[0]]:=i;
for j:=2 to 1000000 div i do
begin
bz[j*i]:=true;
end;
end;
end;
u:=n;
for i:=1 to op[0] do
begin
if op[i]>u then
begin
break;
end;
if u mod op[i]=0 then
begin
inc(p[0]);
p[p[0]]:=op[i];
q[p[0]]:=1;
u:=u div op[i];
end;
while u mod op[i]=0 do
begin
inc(q[p[0]]);
u:=u div op[i];
end;
end;
for i:=1 to p[0] do q[i]:=q[i]*m;
ans:=1;
for l:=1 to p[0] do
begin
fillchar(f,sizeof(f),0);
f[0,0]:=1;
for i:=1 to 2*m do
begin
for j:=0 to q[l] do
begin
for k:=0 to min(j,q[l] div m) do
begin
f[i,j]:=(f[i,j]+f[i-1,j-k]) mod mo;
end;
end;
end;
ans:=(ans*f[2*m,q[l]]) mod mo;
end;
ano:=0;
for i:=1 to trunc(sqrt(n)) do
begin
if n mod i=0 then
begin
ano:=ano+1;
if sqr(i)<n then ano:=ano+1;
end;
//ano:=(ano*((ksm(p[i],q[i]+1)-1)*ksm(p[i]-1,mo-2)) mod mo) mod mo;
end;
ans:=ans+ksm(ano,2*m);
writeln((ans*ksm(2,mo-2)) mod mo);
end.