这个题与上次那个题类似,也是个狄雷克卷积的。
但是这题k很大,不能用快速幂了,那我们就要充分考虑 multiplicative function的性质。具体的过程51nod上面给了很清楚了,主要是给出线性筛部分的代码(这个也是借鉴别人的,侵删)。还有要开读入挂。
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
using namespace std;
typedef long long LL;
const LL mod = 1e9 + 7;
const int maxn = 500000 + 5;
LL inv[100];
LL f[maxn],g[maxn],fg[maxn];
LL n,k;
LL In()
{
char c = getchar();
LL num = 0;
while(!isdigit(c)) c = getchar();
while(isdigit(c)) {
num = num * 10 + c - '0';
if(num >= mod)
num %= mod;
c = getchar();
}
return num;
}
LL mod_pow(LL a, LL n){
LL ret = 1;
while(n > 0){
if(n & 1) ret = ret * a % mod;
a = a * a % mod;
n >>= 1;
}
return ret;
}
void Out(LL x)
{
if(x > 9)
Out(x / 10);
putchar(x % 10 + '0');
}
void init(){
inv[0] = 1;
for(int i = 1;i < 100;i++){
inv[i] = mod_pow(i,mod - 2);
}
}
void dirichlet(LL f[],LL g[],LL fg[],int n){
for(int i = 1;i <= n;i++) fg[i] = 0;
for(int i = 1;i * i <= n;i++){
for(int j = i;j * i <= n;j++){
if(i == j) fg[i * j] = (fg[i * j] + f[i] * g[j]) % mod;
else fg[i * j] = (fg[i * j] + f[i] * g[j] + f[j] * g[i]) % mod;
}
}
}
void solve(int k){
g[1] = 1;
LL *prime = fg;
int tot = 0;
for(int i = 2;i <= n;i++){
if(!prime[i]) prime[tot++] = i,g[i] = k;
for(int j = 0;j < tot && prime[j] * i <= n;j++){
prime[prime[j] * i] = 1;
int r = 1,x = i;
while(x % prime[j] == 0) r++,x /= prime[j];
g[i * prime[j]] = 1LL * g[i] * (r + k - 1) % mod * inv[r] % mod;
if(r != 1) break;
}
}
dirichlet(f, g, fg, (int)n);
for(int i = 1;i <= n;i++){
Out(fg[i]);
if(i < n) putchar(' ');
else putchar('\n');
}
}
int main(int argc, const char * argv[]) {
init();
n = In();
k = In();
for(int i = 1;i <= n;i++) f[i] = In();
solve(k);
return 0;
}