Codeforces E. Bash Plays with Functions(积性函数DP)

链接

codeforces

题解

结论:\(f_0(n)=2^{n的质因子个数}\)=
根据性质可知\(f_0()\)是一个积性函数
对于\(f_{r+1}()\)化一下式子
对于

\[f_{r+1} = \sum_{d|n}f_r(d) \]

\(f_r+1\)可以看做\(f_r()\)\(g(d)\)的狄利克雷卷积因为\(f_0()\)是积性函数,\(g(d)\)也是积性函数,由卷积性质得\(f_{r+1}()\)也是积性函数,那么\(f_r\)同理
对于\(n\)质因数分解得到:

\[n=p_1^{e_1}*p_2^{e_2}* \cdots *p_k^{e_k} \]

那么:

\[f_r(n)=f_r(p_1^{e_1})*f_r(p_2^{e_2})* \cdots *f_r(p_k^{e_k}) \]

对于\(p_i^{e_i}\)的所有因子个数为\(p^{ \{0,1,2,\cdots e_i \} }\)
可以看出,质因子的因字数时与\(p\)无关的
然后就可以dp预处理出,在\(f_i\)中i中的\(e\)次方的函数值
用f[i][j]表示\(f_i(p^j)\)那么f[i][j]=\(\sum_{k=0}^{j} dp[i-1][k]\)

代码

#include<cstdio>
#include<cmath>
#include<iostream>

int Q;

const int maxn = 10001;
const int mod = 1e9+7;
inline int read() {
	int x=0;char c=getchar();
	while(c<'0'||c>'9') c=getchar();
	while(c<='9'&&c>='0')x=x*10+c-'0',c=getchar();
	return x;
}

int prime[maxn],num=0;
bool vis[maxn];
int f[maxn*100][22];
void init() {
	for(int i=2;i<=maxn;++i) {
		if(!vis[i]) prime[++num]=i;
		for(int j=1;j<=num&&i*prime[j]<maxn;++j) {
			vis[i*prime[j]]=1;
			if(!(i%prime[j]))break;
		}
	}
	for(int i=1;i<=20;++i) f[0][i]=2;f[0][0]=1;
	for(int sum=0,i=1;i<=maxn*100;++i) {
		for(int j=0;j<=20;++j) {
			sum+=f[i-1][j];sum%=mod;
			f[i][j]+=sum;f[i][j]%=mod;
		}
		sum=0;
	}
}
int solve(int a,int b) {
	int ans=1;int st=sqrt(b)+0.5;
	for(int cnt=0,i=1;i<=num&&prime[i]<=st;++i) {
		cnt=0;
		while(!(b%prime[i]))cnt++,b/=prime[i];
		ans=(1LL*ans*f[a][cnt])%mod;
	}
	if(b>1)ans=(1LL*ans*f[a][1])%mod;
	printf("%d\n",ans);
}
int main() {
	init();
	Q=read();
	for(int a,b;Q--;) {
		a=read();b=read();
		solve(a,b);
	}
	return 0;
}
posted @ 2018-02-06 18:01  zzzzx  阅读(223)  评论(0编辑  收藏  举报