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;
}
posted @ 2019-07-06 11:14  菜狗xzz  阅读(215)  评论(0编辑  收藏  举报