表示题解给的卷积没看懂,不能理解。。
#include <iostream>
#include <algorithm>
#include <cstdio>
#include <vector>
#include <cstring>
#include <queue>
#include <climits>
#include <cmath>
#include <map>
#include <set>
#define LL long long
#define pr pair < int, int >
using namespace std;
vector <LL> v[110005],w[110005];
LL MOD=1000000007;
int n,k;LL a[110005];
LL f[110005],fac[200005],inv[200005];
LL pow_mod(LL a,LL b,LL m){
LL ans=1LL;
a%=m;
while(b){
if(b&1)ans=ans*a%m;
a=a*a%m;
b>>=1;
}
return ans;
}
LL c(LL n,LL m){
if(n<m||n<0||m<0)return 0;
return fac[n]*inv[m]%MOD*inv[n-m]%MOD;
}
int main()
{
fac[0]=1LL;
for(LL i=1;i<=101000;++i){
fac[i]=i*fac[i-1]%MOD;
}
inv[101000]=pow_mod(fac[101000],MOD-2,MOD);
for(LL i=101000-1;i>=0;--i){
inv[i]=inv[i+1]*(i+1)%MOD;
}
for(LL i=1;i<=101000;++i){
for(LL j=1;j*j<=i;++j){
if(i%j==0){
if(i!=j*j){
v[i].push_back(j);
v[i].push_back(i/j);
}
else v[i].push_back(j);
}
}
}
for(LL i=1;i<=101000;++i){
LL now=i,cnt=0LL;
for(LL j=2;j*j<=i;++j){
if(now%j==0){
while(now%j==0){
++cnt;
now/=j;
}
w[i].push_back(cnt);
cnt=0LL;
}
}
if(now!=1LL)w[i].push_back(1LL);
}
int T;
scanf("%d", &T);
while(T--)
{
scanf("%d%d",&n,&k);
for(int i=1;i<=n;++i)scanf("%I64d",a+i);
int len;k--;
for(int i=1;i<=n;++i){
len=w[i].size();
f[i]=1LL;
for(int j=0;j<len;++j){
f[i]*=c(k+w[i][j],k);
f[i]%=MOD;
}
}
LL ans;
for(int i=1;i<=n;++i){
ans=0LL;len=v[i].size();
for(int j=0;j<len;++j){
ans+=(LL)a[v[i][j]]*f[i/v[i][j]];
if(ans>=MOD)ans%=MOD;
}
if(i!=1)putchar(' ');
printf("%I64d",ans);
}
puts("");
}
return 0;
}