这个jzoj到底是个什么神仙OJ…
所以不负责的博主就不贴链接直接贴截图了。。。
题面
Solution
其实这道题作为模拟赛的T3的确是偏水了一点
然而我这只菜鸡还是写炸了。。
这是份假的代码 应该可以很容易看出我原来的zz错误
#include <cstdio>
#include <algorithm>
#define MOD 998244353
using namespace std;
typedef long long LL;
LL dp[300000][110];
inline LL qui_pow(LL x, int y) {
if (y == 1) return x;
LL t = qui_pow(x, y / 2);
if (y & 1) return t * t % MOD * x % MOD;
else return t * t % MOD;
}
int main() {
freopen("count.in", "r", stdin);
freopen("count.out", "w", stdout);
int n, m, tot = 1;
scanf("%d%d", &n, &m);
int nn = n;
for (int i = 2; i * i <= n; ++i) {
if (!(nn % i)) {
int cnt = 1;
while (!(nn % i)) {
nn /= i;
cnt++;
}
tot *= cnt;
}
}
if (nn > 1) tot <<= 1;
int lim = (tot + 1) * m;
dp[0][0] = 1;
for (int i = 1; i <= lim; ++i) {
for (int j = 1; j <= m * 2; ++j) {
for (int k = 1; k <= min(i, tot); ++k) {
dp[i][j] += dp[i - k][j - 1];
}
dp[i][j] %= MOD;
}
}
LL ans = (qui_pow(tot, m << 1) + dp[lim][m * 2]) * qui_pow(2, MOD - 2) % MOD;
printf("%lld\n", ans);
fclose(stdin); fclose(stdout);
return 0;
}
(手动分割线)
Solution
我们令
S
=
∏
i
=
1
2
m
x
i
S=\prod_{i=1}^{2m}x_i
S=∏i=12mxi
所以当
S
<
n
m
S<n^m
S<nm时就一定存在一个对应的一个
S
′
>
n
m
S'>n^m
S′>nm,这个很显然对叭
所以我们现在要做的就是求出
S
=
n
m
S=n^m
S=nm有多少不同的方案数
我们设这个方案数为
c
n
t
cnt
cnt
∴
a
n
s
=
σ
(
n
)
2
m
+
c
n
t
2
\therefore ans=\frac{\sigma(n)^{2m}+cnt}{2}
∴ans=2σ(n)2m+cnt
那么问题来了,如何求
c
n
t
cnt
cnt呢?
根据乘法原理,可以发现对于
n
m
n^m
nm的所以质因子都是互相独立的
这样我们就可以对于每个质因子进行整数拆分的操作(这个好像是小学生都会写的dp,而我居然写挂了kel)
除以 2 2 2的时候记得打个逆元。
#include <cstdio>
#include <algorithm>
#include <cstring>
#define MOD 998244353
using namespace std;
typedef long long LL;
LL dp[10000][220], all;
int cc[110];
inline LL qui_pow(LL x, register int y) {
if (y == 1) return x;
LL t = qui_pow(x, y / 2);
if (y & 1) return t * t % MOD * x % MOD;
else return t * t % MOD;
}
int main() {
register int n, m, tot = 1;
scanf("%d%d", &n, &m);
register int nn = n;
for (register int i = 2; i * i <= n; ++i) {
if (!(nn % i)) {
register int cnt = 1;
while (!(nn % i)) {
nn /= i;
cnt++;
}
cc[++cc[0]] = cnt - 1;
tot *= cnt;
}
}
if (nn > 1) tot <<= 1, cc[++cc[0]] = 1;
LL all = 1;
for (register int l = 1; l <= cc[0]; ++l) {
memset(dp, 0, sizeof dp);
register int lim = cc[l] * m;
dp[0][0] = 1;
for (register int i = 0; i <= lim; ++i) {
for (register int j = 1; j <= m * 2; ++j) {
for (register int k = 0; k <= min(i, cc[l]); ++k) {
dp[i][j] += dp[i - k][j - 1];
}
dp[i][j] %= MOD;
}
}
all = all * dp[lim][m << 1] % MOD;
if (all >= MOD) all -= MOD;
}
LL ans = (qui_pow(tot, m << 1) + all) * qui_pow(2, MOD - 2) % MOD;
printf("%lld\n", ans);
return 0;
}