代码
读懂代码前需要掌握的芝士:
唯一分解定理
任意正整数都有且只有一种方式写出其素因子的乘积表达式。
约数和方程
对于已经分解的整数
有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; //输出答案 }