星星之火

[Codeforces 757E] Bash Plays with Functions (数论)

题目链接: http://codeforces.com/contest/757/problem/E?csrf_token=f6c272cce871728ac1c239c34006ae90

题目:

题解:

$f_0(n) = 2^{n的不同质因子的个数}$

$ f_r(n) = \sum_{d|n}f_{r-1}(d)$

$f_0$是积性函数 , $f_r = f_0 * Id^r (1) $也是积性函数 , 所以只需要求$f_r(p^k)$就行了 

$f_r(p^k)$与p无关 , $f_0(p^k)$=1+(k!=0) , $f_r(p^k)$=$\sum_{0<=i<=k}$ $ f_{r-1}(p^i)$

先递推出所有 (r,k) 的函数值, 每个询问只要分解质因数即可

时间复杂度: O((r + q) logn)

代码如下:

#include<iostream>
#include<algorithm>
#include<cstring>
#include<cstdio>
#include<cmath>
using namespace std;
typedef long long ll;

const int N=1e6+15;
const int M=21;
const int mod=1e9+7;
int q,r,n,tot;
int prime[N],vis[N];
ll f[N][22];
inline int read()
{
    char ch=getchar();
    int s=0,f=1;
    while (ch<'0'||ch>'9') {if (ch=='-') f=-1;ch=getchar();}
    while (ch>='0'&&ch<='9') {s=(s<<3)+(s<<1)+ch-'0';ch=getchar();}
    return s*f;
}
void get_prime()
{
    for (int i=2;i<=N;i++)
    {
        if (!vis[i]) prime[++tot]=i;
        for (int j=1;j<=tot&&prime[j]*i<=N;j++)
        {
            vis[prime[j]*i]=1;
            if (i%prime[j]==0) break;
        }
    }
}
void pre()
{
    f[0][0]=1;
    for (int i=1;i<=M;i++) f[0][i]=2;
    for (int i=1;i<=N;i++)
    {
        ll sum=0;
        for (int j=0;j<=M;j++)
        {
            sum+=f[i-1][j];
            f[i][j]=(f[i][j]+sum)%mod;
        }
    }
}
int main()
{
    get_prime();
    pre();
    q=read();
    while (q--)
    {
        r=read();n=read();
        ll ans=1;
        for (int i=1;i<=tot&&prime[i]<=sqrt(n);i++)
        {
            if (n%prime[i]) continue;
            int num=0;
            while (n%prime[i]==0) n/=prime[i],num++;
            ans=1ll*ans*f[r][num]%mod;
        }
        if (n>1) ans=1ll*ans*f[r][1]%mod;
        printf("%I64d\n",ans);
    }
    return 0;
} 

 

  

posted @ 2018-08-24 22:32  星星之火OIer  阅读(193)  评论(0编辑  收藏  举报