题面
题解
看到这题第一眼只会 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)\)。
推下式子:
\[ \begin{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) g\left(\frac nd\right) = \frac 1k \sum_{d|n} f(d)g'\left(\frac nd\right) \\\Rightarrow \ &f'(n)g(1) + \sum_{d|n, d \neq n} f'(d) g\left(\frac nd\right) = \frac 1k \left[f(n)g'(1) + \sum_{d|n, d\neq n} f(d)g'\left(\frac nd\right)\right]\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
#include
#include
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], " \n"[i == n]);
return 0;
}