@ljt12138
2017-05-31T15:37:47.000000Z
字数 2054
阅读 877
给定在上的取值,求函数:
在上的取值。
容易发现,,直接用狄利克雷卷积快速幂即可。
显然,的所有因子在整除关系下构成一个偏序,可以等价地转化为一张带自环而无其他环的图。则从开始的序列与有向无环图上从开始长度为的路径一一对应。
考虑求从开始长度为的路径所有终点位置的和,容易写出方程:
然而这个dp的状态规模是的,考虑原因:存在很长的链是因为可以多次在一个数上重复(即在自环上走)。设为长度为从开始长度为的所有不经过自环的终点位置的和,则:
显然,现在向路径上插入自环。考虑对的贡献,。需要在个位置上插入个自环,用隔板法分析可知为:,因此:
而答案等于的所有因子的的和,即:
自此问题得以解决。复杂度。
#include <bits/stdc++.h>
using namespace std;
const int MAXN = 100005;
struct node {
int to, next;
} edge[MAXN*20];
int head[MAXN], top = 0;
inline void push(int i, int j)
{ edge[++top] = (node){j, head[i]}, head[i] = top; }
int n, k;
void init()
{
for (register int i = 1; i <= 100000; i++)
for (register int j = 2; j*i <= 100000; j++)
push(j*i, i);
}
long long f[MAXN][20], a[MAXN];
const long long mod = 1000000007ll;
long long fac[MAXN], inv[MAXN], g[MAXN], g2[MAXN];
long long power(int a, long long n)
{
if (n == 0) return 1;
long long b = a, ans = 1;
for (int k = 0; k <= 30; k++) {
if (n&(1ll<<k)) (ans *= b) %= mod;
(b *= b) %= mod;
}
return ans;
}
inline long long choose(int K, int k)
{ return fac[K]*inv[k]%mod*inv[K-k]%mod; }
void init_c()
{
inv[0] = 1;
for (int i = 1; i <= 100000; i++) inv[i] = (inv[i-1]*power(i, mod-2))%mod;
fac[0] = 1;
for (int i = 1; i <= 100000; i++) (fac[i] = fac[i-1]*i) %= mod;
}
void dp()
{
scanf("%d%d", &n, &k);
for (int i = 1; i <= n; i++) scanf("%lld", &f[i][1]);
for (int j = 2; j <= 17; j++)
for (register int i = 1; i <= n; i++) {
f[i][j] = 0;
for (register int k = head[i]; k; k = edge[k].next) {
int to = edge[k].to;
(f[i][j] += f[to][j-1]) %= mod;
}
}
for (register int i = 1; i <= n; i++) {
long long ans = 0;
for (register int j = 1; j <= 17; j++)
(ans += f[i][j]*choose(k-1, j-1)%mod) %= mod;
g[i] = ans;
}// cerr << endl;
memset(g2, 0, sizeof g2);
for (register int i = 1; i <= n; i++)
for (register int j = 1; j*i <= n; j++)
(g2[j*i] += g[i]) %= mod;
for (int i = 1; i <= n; i++)
printf("%lld ", g2[i]);
puts("");
}
int main()
{
freopen("b.in", "r" , stdin);
freopen("b.out", "w", stdout);
init();
init_c();
int T; scanf("%d", &T);
while (T--) dp();
return 0;
}