根据唯一分解定理可以把A分解为质因数,表示为p1^c1 * p2^c2 * p3^c3 ...... * pn^cn
那么A^B表示为p1^(B*c1) * p2^(B*c2) * p3^(B*c3) ...... * pn^(B*cn)
A^B的所有约数表示为{p1^k1 * p2^k2 * ... * pn^kn 其中0<= ki <= B * ci (1 <= i <=n)
所以根据成打分配律,A^B 的所有约数之和就是:
(1 + p1 + p1^2 + ...+ p1^(B*c1) ) * (1 + p2 + p2^2 + ...+ p2^(B*c2) ) * ... * (1 + pn + pn^2 + ...+ pn^(B*cn) )
上式中的每个括号内都是等比数列,如果使用等比数列求和公式,需要做除法。而答案还需要模一个数X,mod运算只对加 减 乘有分配律,不能对分子,分母分别取模后再做除法。
然而,可以使用分治法来进行 等比数列求和
sum(p,c)=1 + p + p^2 + ... +p^c = ?
若c为奇数:
sum(p,c) = (1 + p + ... + p^((c-1)/2) + (p^((c+1)/2) + ... + p^c)
= (1 + p + ... + p^((c-1)/2) + p^((c+1)/2) * ( 1 + p + ... + p^((c-1)/2)
= (1 + p^((c+1)/2) * sum(p, (c-1)/2);
若c为偶数
同理 sum(p,c) = (1 + p^(c/2)) * sum(p,c/2 - 1) + p^c
每次分治(即递归之后),问题的规模会缩小一半,配合快速幂即可在O(log c )的时间内求出等比数列的和
附代码:
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define mod 9901
ll ksm(ll a,ll b)
{
ll ans=1;
while(b)
{
if(b&1) ans=ans*a%mod;
a=a*a%mod;
b>>=1;
}
return ans;
}
ll sum( ll p, ll c)
{
if(c==0)
return 1;
if(c&1)
return ((1+ksm(p,(c+1)/2))*sum(p,(c-1)/2))%mod ;
else
return ((1+ksm(p,c/2))*sum(p,c/2-1)+ksm(p,c))%mod;
}
int main()
{
ll a,b;
ll ans=1;
cin>>a>>b;
for(ll i=2;i<=a;i++)
{
ll s=0;
while(a%i==0)
{
s++;
a/=i;
}
ans=ans*sum(i,s*b)%mod;
}
if(a==0)
cout<<"0"<<endl;
else
cout<<ans<<endl;
return 0;
}