题目描述
给定\(f(i)\),已知\(g(i)=\sum_{i_1|i}\sum_{i_2|i_1}...\sum_{i_k|i_{k-1}}f(i_k)\),求\(g(i)\)。
思路
先给出dirichlet卷积的定义:\((f*g)(n)=\sum_{d|n}f(d)g(\frac{n}{d})\),满足结合律。
因此题目要求的东西为\(g=I^k*f\),用快速幂计算即可。
#include <bits/stdc++.h>
using namespace std;
s
typedef long long ll;
const int MAXN = 100000 + 10;
const int MOD = 1000000007;
int n, k;
ll f[MAXN], I[MAXN], e[MAXN];
void init()
{
for (int i = 1; i <= n; ++i)
I[i] = 1;
memset(e, 0, sizeof(e));
e[1] = 1;
}
void convolution(ll a[], ll b[])
{
static ll temp[MAXN];
memset(temp, 0, sizeof(temp));
for (int i = 1; i * i <= n; ++i) {
temp[i * i] = (temp[i * i] + a[i] * b[i]) % MOD;
for (int j = i + 1; j * i <= n; ++j)
temp[i * j] = (temp[i * j] + a[i] * b[j] + a[j] * b[i]) % MOD;
}
memcpy(a, temp, sizeof(temp));
}
int main()
{
ios::sync_with_stdio(0);
int T;
cin >> T;
while (T--) {
cin >> n >> k;
init();
for (int i = 1; i <= n; ++i)
cin >> f[i];
while (k) {
if (k & 1)
convolution(e, I);
convolution(I, I);
k >>= 1;
}
convolution(f, e);
for (int i = 1; i <= n; ++i)
cout << f[i] << (i == n ? '\n' : ' ');
}
}