卧薪尝胆,厚积薄发。
提高A组模拟 计算
Date: Thu Aug 16 07:36:50 CST 2018
In Category:
NoCategory
Description:
给定
$n$
,求合法的
$\{x_1,x_2,x_3,\dots,x_{2m}\}$
组数,一组
$\{x\}$
是合法的当且仅当
- $\forall i\in[1,2m],\ x_i\in Z^+,\ x_i|n$
- $\begin{align}\prod_{i=1}^{2m}x_i\le n^m\end{align}$
$1\le n \le 10^9$
$m \le 100$
Solution:
若一组
$\{x_1,x_2,x_3,\dots,x_{2m}\}< n^m$
,那么
$\{\frac n{x_1},\frac n{x_2},\frac n{x_3},\dots,\frac n{x_{2m}}\}>n^m$
,设小于
$n^m$
的组数记为
$S_1$
,等于
$n^m$
的组数记为
$S_2$
,大于的记为
$S_3$
,那么由于
$S_1$
和
$S_3$
中的方案一一对应,所以
$S_1=S_3$
,由于
$S_1+S_2+S_3=\sigma_0(n)^{2m}$
,所以只要计算出
$S_2$
即可,可以把每一个质因数分别考虑,
$f[i][j]$
表示
$i$
个人指数和为
$j$
,转移时直接枚举最后一个数的指数转移。
Code:
nclude<algorithm>
#include<iostream>
#include<cstdlib>
#include<cstdio>
#include<cmath>
#include<cstring>
using namespace std;
int n,m;
#define MAXM 101
typedef long long ll;
ll f[MAXM << 1][31 * MAXM];
int sigma0 = 0;
int fac[MAXM],cnt[MAXM],tot = 0;
#define MOD 998244353
ll power(ll a,int b)
{
ll res = 1;
while(b > 0)
{
if(b & 1)res = res * a % MOD;
a = a * a % MOD;
b = b >> 1;
}
return res;
}
int main()
{
freopen("count.in","r",stdin);
freopen("count.out","w",stdout);
cin >> n >> m;
int s = n;
for(int i = 1;i * i <= n;++i)
{
if(n % i == 0)
{
++sigma0;
if(i * i != n)
{
++sigma0;
}
}
}
for(int i = 2;i * i <= n;++i)
{
if(s % i == 0)
{
fac[++tot] = i;
while(s % i == 0){s /= i;++cnt[tot];}
}
}
if(s != 1)fac[++tot] = s,cnt[tot] = 1;
ll S2 = 1;
for(int k = 1;k <= tot;++k)
{
memset(f,0,sizeof(f));
f[0][0] = 1;
for(int i = 1;i <= 2 * m;++i)
{
for(int j = 0;j <= cnt[k] * m;++j)
{
for(int l = 0;l <= cnt[k];++l)
{
if(j - l >= 0)f[i][j] = (f[i][j] + f[i - 1][j - l]) % MOD;
}
}
}
S2 = (S2 * f[2 * m][cnt[k] * m]) % MOD;
}
cout << (power(sigma0,2 * m) + S2) % MOD * power(2,MOD - 2) % MOD << endl;
fclose(stdin);
fclose(stdout);
return 0;
}
Copyright © 2020
wjh15101051
ღゝ◡╹)ノ♡