Acwing 97
Acwing 97. 约数之和
题意
求\(a^b\)的约数之和
思路
假设不考虑次方,只求a的约数之和,要怎么求呢?
当遇到一个数b能被a整除时,假设当前答案为\(ans\),则应再加上\(ans*b\)。
a经过质数分解定理后为\(p_1^{k1}p_3^{k3}p_3^{k3}...\)
当增加一个质数约数\(c^x\)时,则答案应变为\(ans*\sum_0^{i=x}c^i\),
运用快速幂的思想 ,当x为奇数,则有偶数个项,\(\sum_0^{i=x}c^i =(\sum_0^{i=\frac{x}{2}}c^i)*(c^{\lceil \frac{x}{2} \rceil}+1)\)
当x为偶数,则将x-1代入上式,多出的那个直接加到答案中
代码
int q_pow(int a,int b)
{
int res=1;
while(b)
{
if(b&1) res=(res*a)%mod;
a=a*a%mod;
b/=2;
}
return res;
}
int cal(int a,int b)
{
if(b==0) return 1ll;
int res=0;
if(b&1)
{
int k1=cal(a,b/2)%mod;
int k2=(q_pow(a,(b+1)/2)+1)%mod;
res=(res+k1*k2%mod)%mod;
}
else
{
res=(res+q_pow(a,b))%mod;//多出来的那个
int k1=cal(a,(b-1)/2)%mod;
int k2=(q_pow(a,b/2)+1)%mod;
res=(res+k1*k2%mod)%mod;
}
return res;
}
void solve()
{
cin>>n>>m;
ans=1;
if(n==0) {cout<<0<<endl;return;}
for(int i=2;i<=n;i++)
{
if(n%i==0)
{
int cnt=0;
while(n%i==0) cnt++,n/=i;
// ans*(i)
if(i*m>0) ans=(ans*cal(i,cnt*m))%mod;
}
}
cout<<ans<<endl;
}