传送门
这个东西在r=0的时候,就是
f0(n)=2(n的质因子个数)
然后这个东西明显是个积性函数
然后题目里给的式子其实就是代表
fr+1=fr∗1
然后因为
f0和1
都是积性函数,那么当
r∈N
时都满足
fr
是积性函数
然后我们有这样一个递推式
dp[i][j]=∑jk=0dp[i−1][k]
我们可以前缀和优化,做到
O(rlogn)
预处理,
O(logn)
回答询问
代码:
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<iostream>
#include<algorithm>
#define ll long long
#define max(a,b) a>b?a:b
#define min(a,b) a<b?a:b
using namespace std;
inline int read(){
int x=0,f=1;char ch=' ';
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9')x=(x<<3)+(x<<1)+(ch^48),ch=getchar();
return x*f;
}
const int N=1e6+5,p=1e9+7;
const int maxn=1e6,logn=20,maxp=1000;
int T,r,n;
int vis[N],prime[N],cnt;
int dp[N][logn+1],sum[N][logn+1];
inline void init(){
for(int i=2;i<=maxp;i++){
if(!vis[i])prime[++cnt]=i;
for(int j=1;j<=cnt&&i*prime[j]<=maxp;j++){
vis[i*prime[j]]=1;
if(i%prime[j]==0)break;
}
}
dp[0][0]=sum[0][0]=1;
for(int i=1;i<=logn;i++)dp[0][i]=2;
for(int i=1;i<=logn;i++)sum[0][i]=sum[0][i-1]+dp[0][i];
for(int i=1;i<=maxn;i++)
for(int j=0;j<=logn;j++){
dp[i][j]=sum[i-1][j];
if(j>0)sum[i][j]=sum[i][j-1]+dp[i][j];
else sum[i][j]=dp[i][j];
if(sum[i][j]>=p)sum[i][j]-=p;
}
}
inline int solve(){
int lim=sqrt(n+0.5);int ans=1;
for(int j=1;j<=cnt&&prime[j]<=lim;j++){
if(n%prime[j]==0){
int cnt=0;
while(n%prime[j]==0)n/=prime[j],cnt++;
ans=(1LL*ans*dp[r][cnt])%p;
}
}
if(n>1)ans=(1LL*ans*dp[r][1])%p;
return ans;
}
int main(){
init();
T=read();
while(T--){
r=read();n=read();
printf("%d\n",solve());
}
return 0;
}