题解 P6060 【[加油武汉]传染病研究】
为了刷点社区贡献我来写题解。
啊
我们知道
然后我们发现,
所以
不妨举个例子,比如
展开一下:
啊,原来是一个关于
为啥是
也就是说,有多少个质因子就是关于
然而
所以说啊,对于任何
众所周知,无论多少个
如果我们已经得到了,每个
所以写个线筛就可以求多项式的系数了,然后做一下前缀和,就做完了。
代码如下,时间复杂度为
#include <cstdio>
#include <cstring>
typedef long long LL;
const int Mod = 998244353;
const int MN = 10000007, MP = 664580;
bool ip[MN];
int p[MP], pc;
int lpf[MN], lpfc[MN], dlpf[MN];
int poly[MN][9];
void Sieve(int N) {
poly[1][0] = 1;
for (int i = 2; i <= N; ++i) {
if (!ip[i]) p[++pc] = i, lpf[i] = i, lpfc[i] = 1, dlpf[i] = 1, poly[i][0] = poly[i][1] = 1;
for (int j = 1, k; j <= pc; ++j) {
if ((k = p[j] * i) > N) break;
ip[k] = 1;
lpf[k] = j;
if (i % p[j]) lpfc[k] = 1, dlpf[k] = i;
else lpfc[k] = lpfc[i] + 1, dlpf[k] = dlpf[i];
memcpy(poly[k], poly[dlpf[k]], 36);
for (int z = 8; z >= 1; --z) poly[k][z] = (poly[k][z] + (LL)lpfc[k] * poly[k][z - 1]) % Mod;
if (i % p[j] == 0) break;
}
}
for (int i = 1; i <= N; ++i)
for (int j = 0; j <= 8; ++j)
poly[i][j] -= (poly[i][j] += poly[i - 1][j]) >= Mod ? Mod : 0;
}
int main() {
Sieve(10000000);
int T;
scanf("%d", &T);
while (T--) {
int N, K;
scanf("%d%d", &N, &K);
int Ans = 0;
for (int i = 8; i >= 0; --i)
Ans = ((LL)Ans * K + poly[N][i]) % Mod;
printf("%d\n", Ans);
}
return 0;
}