题面
题解
看到这题第一眼只会 k = 2,百度搜一下「狄利克雷卷积」后得知有一个非常神仙的东西:狄利克雷生成函数。它大概长这样:
[F(z) = sum_{n geq 1} frac {f(n)}{n^z}
]
显然这个函数的卷积对应数论函数 (f) 的狄利克雷卷积。
可以发现 (displaystyle F'(z) = sum_{n geq 1} frac{f(n)ln n}{n^z}),于是记 (f'(n) = f(n) ln n)。
于是题目就变成了求函数 (F(x)) 使得 (F(x)^k = G(x))。
推下式子:
[egin{aligned}&F^k = G \Rightarrow &kF^{k - 1}F' = G' \Rightarrow &kF'frac{G}{F} = G' \Rightarrow &F'G = frac 1k G'F \Rightarrow &sum_{d|n} f'(d) gleft(frac nd
ight) = frac 1k sum_{d|n} f(d)g'left(frac nd
ight) \Rightarrow &f'(n)g(1) + sum_{d|n, d
eq n} f'(d) gleft(frac nd
ight) = frac 1k left[f(n)g'(1) + sum_{d|n, d
eq n} f(d)g'left(frac nd
ight)
ight]end{aligned}
]
由于 (g(1) = 1, g'(1) = 0),所以可以求出 (f'(n)),进而求出 (f(n))。
然后这道题就做完了...... 等等,(ln n) 在模意义下是什么东西(
考虑用一些可以替代 (ln n) 的东西。
令 (f'(n) = c(n) f(n)),若要满足求导的所有性质,就需要使 (c) 满足 (c(nm) = c(n) + c(m))。
于是令 (c(n)) 表示 (n) 的质因数个数即可。
代码
#include <cstdio>
#include <algorithm>
#include <vector>
inline int read()
{
int data = 0, w = 1; char ch = getchar();
while (ch != '-' && (ch < '0' || ch > '9')) ch = getchar();
if (ch == '-') w = -1, ch = getchar();
while (ch >= '0' && ch <= '9') data = data * 10 + (ch ^ 48), ch = getchar();
return data * w;
}
const int N(1e6 + 10), Mod(998244353);
int n, K, f[N], g[N], p[N], q[N], v[N];
int prime[N], not_prime[N], cnt, num[N];
int fastpow(int x, int y)
{
int ans = 1;
for (; y; y >>= 1, x = 1ll * x * x % Mod)
if (y & 1) ans = 1ll * ans * x % Mod;
return ans;
}
void Init()
{
not_prime[1] = 1, num[1] = 0;
for (int i = 1; i <= n; i++)
{
if (!not_prime[i]) prime[++cnt] = i, num[i] = 1;
for (int j = 1; j <= cnt && i * prime[j] <= n; j++)
{
not_prime[i * prime[j]] = 1, num[i * prime[j]] = num[i] + 1;
if (!(i % prime[j])) break;
}
}
}
int main()
{
n = read(), K = fastpow(read(), Mod - 2), Init();
for (int i = 1; i <= n; i++) v[i] = 1ll * (g[i] = read()) * num[i] % Mod;
for (int i = 1; i <= n; i++)
{
int d = (1ll * K * q[i] - p[i] + Mod) % Mod;
if (i == 1) f[i] = 1, d = 0;
else f[i] = 1ll * d * fastpow(num[i], Mod - 2) % Mod;
for (int j = 1; j * i <= n; j++)
p[j * i] = (p[j * i] + 1ll * d * g[j]) % Mod,
q[j * i] = (q[j * i] + 1ll * f[i] * v[j]) % Mod;
}
for (int i = 1; i <= n; i++)
printf("%d%c", f[i], "
"[i == n]);
return 0;
}