题意:求A^B的所有约数之和,并对其取模 9901。
定理:
(1) 整数的唯一分解定理:
A=(p1^k1)*(p2^k2)*(p3^k3)*....*(pn^kn) 其中pi均为素数
(2) 约数和公式:
对于已经分解的整数A=(p1^k1)*(p2^k2)*(p3^k3)*....*(pn^kn)
A的约数和为S = (1+p1+p1^2+p1^3+...p1^k1) * (1+p2+p2^2+p2^3+….p2^k2) * (1+p3+ p3^3+…+ p3^k3) * .... * (1+pn+pn^2+pn^3+...pn^kn)
思路:二分
#include <iostream>
using namespace std;
#define ll long long
#define mod 9901
#define maxn 50000005
ll fac[100];
ll num[maxn];
ll cnt;
ll solve (ll p,ll n)//二分求(p^n)%mod
{
if(n==1) return p%mod;
ll temp = solve(p,n/2);
if(n%2==0)
return ((temp%mod)*(temp%mod))%mod;
else
return ((p%mod)*(temp%mod)*(temp%mod))%mod;
}
ll aa(ll p,ll n)//二分求(p^1+p^2+...+p^n)%mod
{
if(n==0) return 0;
if(n%2==0)
return ((aa(p,n/2)%mod)*(solve(p,n/2)+1))%mod;
else return (solve(p,n)+aa(p,n-1))%mod;
}
void bb(ll p,ll n) //质因数分解
{
cnt=0;
for(ll i=2;i*i<=p;++i)
{
ll count=0;
if(p%i!=0) continue;
while(p%i==0)
{
count++;
p/=i;
}
fac[cnt]=i;
num[cnt]=count*n;
cnt++;
}
if(p!=1)
{
fac[cnt]=p;
num[cnt]=n;
cnt++;
}
}
int main()
{
ll n,p,r;
while (cin>>p>>n)
{
r=1;
bb(p,n);
for(ll i=0;i<cnt;++i)
{
r=(r*(aa(fac[i],num[i])+1))%mod;
}
cout<<r<<endl;
}
return 0;
}
ps: r =( r *( aa ( fac [ i ], num [ i ])+ 1 ))% mod ; 写成 r *=( aa ( fac [ i ], num [ i ])+ 1 )% mod ; 就wa了??