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;
}

转载于:https://www.cnblogs.com/sssy/p/8413768.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值