这道题目dalao们说数据还可以加强,但是鉴于博主太菜,只会做原题数据。
首先我们只考虑第一个限制
那么分成三类
A:这些x的乘积小于
nm
n
m
B:这些x的乘积等于
nm
n
m
C:这些x的乘积大于
nm
n
m
容易知道A,C的数量是一样的,因为对于每一个A,一定存在一个C使得他们乘积是等于
n2m
n
2
m
这就是本题的重要突破口。
易知,所有情况为
n2m
n
2
m
那么我们只需求出有多少个
(x1,x2,x3,......x2m)
(
x
1
,
x
2
,
x
3
,
.
.
.
.
.
.
x
2
m
)
满足
∏xi
∏
x
i
=
nm
n
m
我们可以发现,对于每个n的质因子p,假设它在n中出现e次,设aj表示
xj
x
j
是它的多少次幂。
那么
∑2mi=1ai=e
∑
i
=
1
2
m
a
i
=
e
那么我们对于每个质因子,做一遍dp
设
fi,j
f
i
,
j
表示做到第i个数,前j个数选数和为j
code
#include<cstdio>
#include<algorithm>
#include<math.h>
#include<cstring>
#define fo(i,a,b) for (int (i)=(a);(i)<=(b);(i)++)
using namespace std;
typedef long long ll;
const int mo=998244353;
int f[205][4000],n,m,p[35000],e[35000],cnt;
ll s1,s2=1ll,s3,s4,x=1ll;
ll power(ll a,int b){
ll t=1ll,y=a%mo;
while (b){
if (b&1) t=t%mo*y%mo;
y=y%mo*y%mo;
b=b/2;
}
return t%mo;
}
int main()
{
freopen("count.in","r",stdin);
freopen("count.out","w",stdout);
scanf("%d%d",&n,&m);
int mx=sqrt(n);
int t=n;
fo(i,2,mx){
if (t%i==0){
p[++cnt]=i;
while (t%i==0){
e[cnt]++;
t=t/i;
}
x=x*(1+e[cnt]);
}
}
if (t!=1){
p[++cnt]=t;
e[cnt]=1;
x=x*2;
}
s4=power(x,2*m);
fo(l,1,cnt){
memset(f,0,sizeof(f));
fo(i,0,e[l]) f[1][i]=1;
fo(i,2,2*m)
fo(j,0,e[l]*m)
fo(k,0,min(e[l],j))
f[i][j]=(f[i][j]+f[i-1][j-k])%mo;
s2=s2*f[2*m][m*e[l]]%mo;
}
ll inv=power(2,mo-2);
s1=(s4-s2)*inv%mo;
s1=((s1%mo)+mo)%mo;
printf("%lld",(s1+s2)%mo);
return 0;
}