51Nod 1769 Clarke and math2
51Nod 1769 Clarke and math2
http://www.51nod.com/Challenge/Problem.html#!#problemId=1769
要算的是\(G=F*I^k\),考虑怎么求\(I^k\)
\(I^k(n=\prod_{i=1}^mp_i^{e_i})=\prod_{i=1}^mC_{e_i+k-1}^{e_i}\)
\(C_{e_i+k-1}^{e_i}\)显然可以直接求。
直接线性筛\(I^k\),然后卷\(F\)。
#include<bits/stdc++.h>
#define il inline
#define vd void
#define mod 1000000007
typedef long long ll;
il ll gi(){
ll x=0,f=1;
char ch=getchar();
while(!isdigit(ch))f^=ch=='-',ch=getchar();
while(isdigit(ch))x=x*10+ch-'0',ch=getchar();
return f?x:-x;
}
il int pow(int x,int y){
int ret=1;
while(y){
if(y&1)ret=1ll*ret*x%mod;
x=1ll*x*x%mod;y>>=1;
}
return ret;
}
int f[500010];
char K[1000010];
int pr[500010],Ik[500010],p,_Ik[500010],d[500010],ans[500010];
bool yes[500010];
int Ck[30];
int main(){
#ifdef XZZSB
freopen("in.in","r",stdin);
freopen("out.out","w",stdout);
#endif
int n=gi(),k=0;scanf("%s",K+1);
int lenk=strlen(K+1);
for(int i=1;i<=lenk;++i)k=(k*10ll+K[i]-'0')%mod;
for(int i=1;i<=n;++i)f[i]=gi();
Ck[0]=1;
for(int i=1;i<30;++i){
Ck[i]=1;
for(int j=1;j<=i;++j)Ck[i]=1ll*Ck[i]*j%mod;
Ck[i]=pow(Ck[i],mod-2);
for(int j=1;j<=i;++j)Ck[i]=1ll*Ck[i]*(i+k-j)%mod;
}
Ik[1]=1;
for(int i=2;i<=n;++i){
if(!yes[i])pr[++p]=i,Ik[i]=Ck[1],_Ik[i]=1,d[i]=1;
for(int j=1;j<=p&&i*pr[j]<=n;++j){
yes[i*pr[j]]=1;
if(i%pr[j]==0){
Ik[i*pr[j]]=1ll*_Ik[i]*Ck[d[i]+1]%mod;
_Ik[i*pr[j]]=_Ik[i];
d[i*pr[j]]=d[i]+1;
break;
}
Ik[i*pr[j]]=1ll*Ik[i]*Ck[1]%mod;
_Ik[i*pr[j]]=Ik[i];
d[i*pr[j]]=1;
}
}
for(int i=1;i<=n;++i)
for(int j=i;j<=n;j+=i)
ans[j]=(ans[j]+1ll*Ik[i]*f[j/i])%mod;
for(int i=1;i<=n;++i)printf("%d ",ans[i]);
return 0;
}
博主是蒟蒻,有问题请指出,谢谢!
本博客中博文均为原创,未经博主允许请勿随意转载,谢谢。
本博客中博文均为原创,未经博主允许请勿随意转载,谢谢。