【分治】 约数之和
传送门
题意
求 \(A^{B}\) 的所有约数的和,答案 \(mod \: 9901\)
数据范围
\(0 \leq A,B \leq 5\times 10^{7}\)
题解
- 唯一分解定律:一个数由质数和合数构成,合数可分解成质数和合数,最后递归下去会变成质数乘积
每一个大于1的数都可以分解成有限个质数的积,不考虑质因数的顺序,分解是唯一的,
将\(A\)分解质因数后表示为:\(P_{1}^{C_{1}} \times P_{2}^{C_{2}} \times \ldots \ldots \times P_{n}^{{C_{n}}}\)
-
\(A^{B}\)约数之和就是
- \(\left(1+P_{1}+P_{1}^{2}+\ldots P_{1}^{B ·C _{1}}\right)\times\left(1+P_{2}+P_{2}^{2}+\ldots P_{2}^{B ·C_{2}}\right)\times \ldots \left(1+P_{n}+P_{n}^{2}+\ldots . P_{n}^{B·C_{n}}\right)\)
上面每个项都是等比数列,等比数列求和需要做除法,结果需要\(mod \: 9901\),模运算只对加、减、乘有分配律
不能直接对分子分母取模再运算,分治、逆元都可以实现在模运算下对等比数列求和
定义\(sum(p,c)\)为公比为\(p\),首项为\(1\),长度为\(c\)的和
-
当\(c\)为奇数时
- \(\begin{aligned} \operatorname{sum}(p, c) &=\left(1+p+\ldots \ldots+p^{\frac{c-1}{2}}\right)+\left(p^{\frac{c+1}{2}}+\ldots \ldots+p ^{c}\right) \\ &=\left(1+p+\ldots \ldots+p^{\frac{c-1}{2}}\right)+p^{\frac{c+1}{2}} \times \left(1+p+\ldots \ldots+p^{\frac{c-1}{2}}\right) \\ &=\left(1+p^{\frac{c+1}{2}}\right)\times\operatorname{sum}(p,\frac{c-1}{2}) \end{aligned}\)
-
当\(c\)为偶数时
- \(\begin{aligned} \operatorname{sum}(p, c) &=\left(1+p+\ldots \ldots+p^{\frac{c}{2}-1}\right)+\left(p^{\frac{c}{2}}+\ldots \ldots+p^{c}\right) \\ &=\left(1+p+\ldots \ldots+p^{\frac{c}{2}-1}\right)+p^{\frac{c}{2} }\times \left(1+p+\ldots \ldots+p^{\frac{c}{2}}\right) \\ &=\left(1+p+\ldots \ldots+p^{\frac{c}{2}-1}\right)+p^{\frac{c}{2}}\left(1+p+\ldots \ldots+p^{\frac{c}{2}-1}\right)+p^{c} \\ &=\left(1+p^{\frac{c}{2}}\right)\times \operatorname{sum}(p, \frac{c}{2}-1)+p^{c} \end{aligned}\)
Code
#include<bits/stdc++.h>
#define rep(i,a,b) for(int i=a;i<b;i++)
#define ll long long
#define mod 9901
using namespace std;
ll powmod(ll a,ll b)
{
ll res=1;
while(b)
{
if(b&1) res=res*a%mod;
a=a*a%mod;
b>>=1;
}
return res;
}
ll sum(int p,int c)
{
if(c==0) return 1;
if(c&1) return (1+powmod(p,(c+1)>>1))%mod * sum(p,(c-1)>>1) %mod;
else return ((1+powmod(p,c>>1))%mod * sum(p,(c-1)>>1)%mod + powmod(p,c))%mod;
}
void solve()
{
ll a,b;
scanf("%lld%lld",&a,&b);
if(a==0) {puts("0"); return 0;}
ll ans=1;
rep(i,2,a+1) // 试除法分解质因数
{
int s=0;
while(a%i==0)
{
s++;
a/=i;
}
if(s) ans= ans %mod * sum(i,s*b) %mod;
}
printf("%lld\n",ans);
}
int main()
{
solve();
}

浙公网安备 33010602011771号