题解
法一:
卷积忘完了,考场上根本没想到。。
可以发现要求的就是
,这里的
是狄利克雷卷积。
然后狄利克雷卷积支持结合律。
所以快速幂就完事了。
时间复杂度
法二:
考虑
对于
的贡献,一定是
的形式,
为一个与
有关的系数。
令 。那么 就是合法的 序列数量, 实质就是 乘上 个数最后变成了 。
容易发现就相当于把 的质因子分在 个盒子里。每个质因子独立可以分开算。假设当前质因子有 个,方案就是
可以通过dfs/线性筛求出 。最后把 卷积一下就算出了答案。
CODE
法一代码:
#include <bits/stdc++.h>
using namespace std;
inline void read(int &x) {
char ch; while(!isdigit(ch=getchar()));
for(x=ch-'0';isdigit(ch=getchar());x=x*10+ch-'0');
}
const int mod = 1e9 + 7;
const int MAXN = 100005;
int n, k, f[MAXN], g[MAXN], tmp[MAXN];
void mul(int *a, int *b) {
for(int i = 1; i <= n; ++i) tmp[i] = 0;
for(int i = 1; i <= n; ++i)
for(int j = i; j <= n; j += i)
tmp[j] = (tmp[j] + 1ll * a[i] * b[j/i]) % mod;
for(int i = 1; i <= n; ++i) a[i] = tmp[i];
}
int main () {
int T; read(T);
while(T--) {
read(n), read(k);
for(int i = 1; i <= n; ++i) read(f[i]), g[i] = 1;
while(k) {
if(k&1) mul(f, g);
mul(g, g); k>>=1;
}
for(int i = 1; i <= n; ++i) printf("%d%c", f[i], " \n"[i==n]);
}
}