题解
设
假设里面的
都是n的约数,
设F(X)表示X里面数的乘积和。
对于的,设
当F(X)<
,则F(X’)>
所以,设有s1个F(X)<
,s2个F(X)=
,s3个F(X)>
。
显然,有个刚刚的结论:s1=s3,
而且我们也知道s1+s2+s3=n的约数个数的2m次方。
于是目标就变为了求s2。
可以知道每个质因子的贡献是独立的,
于是就对于单独的一个质因子考虑它的贡献:
设
表示当前在第i个位置,前面已经用掉了j个质因子的方案数。
每个位置可以不填这个质因子,但最多不能超过n中这个质因子出现的次数,
因为要是x是n的约数。
将每个质因子的贡献乘起来就是s2了。
code
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <string.h>
#include <cmath>
#include <math.h>
#include <time.h>
#define ll long long
#define N 100003
#define M 103
#define db double
#define P putchar
#define G getchar
using namespace std;
char ch;
void read(int &n)
{
n=0;
ch=G();
while((ch<'0' || ch>'9') && ch!='-')ch=G();
ll w=1;
if(ch=='-')w=-1,ch=G();
while('0'<=ch && ch<='9')n=(n<<3)+(n<<1)+ch-'0',ch=G();
n*=w;
}
int max(int a,int b){return a>b?a:b;}
int min(int a,int b){return a<b?a:b;}
void write(ll x){if(x>9) write(x/10);P(x%10+'0');}
const int mo=998244353;
int n,m,p[N],k[N],cnt,f[203][6003],q,s,ss,t;
ll ans;
void add(int& x,int y){x=x+y>=mo?x+y-mo:x+y;}
ll ksm(ll x,int y)
{
ll s=1;
for(;y;y>>=1,x=x*x%mo)
if(y&1)s=s*x%mo;
return s;
}
int main()
{
freopen("count.in","r",stdin);
freopen("count.out","w",stdout);
read(n);read(m);
for(int i=1;i*i<=n;i++)
if(n%i==0)
{
q+=2;
if(n/i==i)q--;
}
s=n;ans=1;
for(int i=2;i*i<=s;i++)
if(s%i==0)
{
for(p[++cnt]=i;s%i==0;s/=i)k[cnt]++;
}
if(s>1)p[++cnt]=s,k[cnt]=1;
for(int i=1;i<=cnt;i++)
{
memset(f,0,sizeof(f));
f[0][0]=1;
for(int j=1;j<=2*m;j++)
{
ss=min(j,m)*k[i];
for(int s=0;s<=ss;s++)
{
t=min(s,k[i]);
for(int w=0;w<=t;w++)
add(f[j][s],f[j-1][s-w]);
}
}
ans=ans*f[2*m][m*k[i]]%mo;
}
ans=(ans+ksm(q,2*m))%mo*ksm(2,mo-2)%mo;
printf("%lld",ans);
return 0;
}