代码
读懂代码前需要掌握的芝士:
唯一分解定理
任意正整数都有且只有一种方式写出其素因子的乘积表达式。
约数和方程
对于已经分解的整数
有A的所有因子之和为
我们先记录素因子,然后利用约数和方程求解。这里有一个二分加速的过程,推导在代码里面。
牛客上面有三道Sumdiv大家可以顺便A了。
思路
#include<iostream>
using namespace std;
const int mod=9901;
typedef long long ll;
ll A,B,k=0;
ll p[20005],n[20005];
ll fpow(ll p, ll n){ //快速幂
ll res=1;
p%=mod;
while(n){
if(n&1) res=res*p%mod;
p=p*p%mod;
n>>=1;
}
return res;
}
ll sum(ll p, ll n){ //求约数和方程的每一项
//递归二分法求等比数列1+pi+pi^2+pi^3+...+pi^ni;
//=(1+p+p^2+...+p^(n/2))*(1+p^(n/2+1))
if(n==0) return 1; //只有p^0这一项
if(n%2){ //n为奇数
return ((sum(p,n/2)%mod)*(1+fpow(p,n/2+1)))%mod;
}else{ //n为偶数
return ((sum(p,n/2-1)%mod)*(1+fpow(p,n/2+1))%mod+fpow(p,n/2))%mod;
}
}
signed main(){
cin>>A>>B;
for(int i=2;i*i<=A;){ //根号法+递归法
if(A%i==0){ //如果i是A的因子
p[++k]=i; //记录所有素因子
n[k]=0;
while(!(A%i)){
n[k]++; //记录素因子的个数
A/=i;
}
}
if(i==2) i++; //奇偶法,2以外的偶数并非素数
else i+=2; //特判:分解整数A(A为质数)
}
if(A!=1){
p[++k]=A;
n[k]=1;
}
if(!A){
cout<<0<<endl;
return 0;
}
ll ans=1; //约数和
for(int i=1;i<=k;i++){
ans=(ans*(sum(p[i],n[i]*B)%mod))%mod; //约数和方程
//n[i]*B可能会超过int,因此用long long
}
cout<<ans<<endl; //输出答案
}

京公网安备 11010502036488号