Description
定义 f0(n) 为满足 p⋅q=n,gcd(p,q)=1 的有序对 (p,q) 对数,定义 fr+1(n)=∑u⋅v=nfr(u)+fr(v)2 ,给出 r,n ,求 fr(n)
Input
第一行一整数
q
表示用例组数,每组用例输入两个整数
Output
对于每组用例,输出 fr(n) ,结果模 109+7
Sample Input
5
0 30
1 25
3 65
2 5
4 48
Sample Output
8
5
25
4
630
Solution
首先证明
f0(n)
是积性函数,对
(n,m)=1
,对
n,m
素因子分解,
n=pa11...pass,m=qb11...qbtt
,则有
pi≠qj
,将
n
拆成两个互素的数
如果 fr(n) 是积性函数,下面证明 fr+1(n) 是积性函数, fr+1(n)=∑u⋅v=nfr(u)+fr(v)2=∑d|nfr(d)+fr(nd)2=12(∑d|nfr(d)+∑d|nfr(nd))=∑d|nfr(d)
故 fr+1(n) 是积性函数,由数学归纳法,对于任意 r≥0 , fr(n) 是积性函数
设 n=pa11...pass ,那么 fr(n)=fr(pa11)fr(pa22)...fr(pass) ,即只要求出 fr(pk) 的值即可,其中 p 为素数
fr(pk)=∑i=0kfr−1(pi)=fr(pk−1)+fr−1(pk),r≥1,k≥1
预处理
dp[k][r]=fr(pk)
,对于每次查询,得到
n
的素因子分解形式中的幂指数
Code
#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<vector>
#include<queue>
#include<map>
#include<set>
#include<ctime>
using namespace std;
typedef long long ll;
typedef pair<int,int>P;
const int INF=0x3f3f3f3f,maxn=1000005;
#define mod 1000000007
int dp[20][maxn];
void add(int &x,int y)
{
x=x+y>=mod?x+y-mod:x+y;
}
void init(int n=19,int r=1e6)
{
dp[0][0]=1;
for(int i=1;i<=r;i++)dp[0][i]=1;
for(int i=1;i<=n;i++)
{
dp[i][0]=2;
for(int j=1;j<=r;j++)
add(dp[i][j],dp[i][j-1]+dp[i-1][j]);
}
}
vector<int>g[maxn];
void Solve(int n)
{
int nn=n;
for(int i=2;i*i<=n;i++)
if(n%i==0)
{
int num=0;
while(n%i==0)n/=i,num++;
g[nn].push_back(num);
}
if(n>1)g[nn].push_back(1);
}
int main()
{
init();
int q,n,r;
scanf("%d",&q);
while(q--)
{
scanf("%d%d",&r,&n);
if(n==1)printf("1\n");
else
{
if(g[n].size()==0)Solve(n);
int ans=1;
for(int i=0;i<g[n].size();i++)ans=(ll)ans*dp[g[n][i]][r]%mod;
printf("%d\n",ans);
}
}
return 0;
}