題解 洛谷P1593 因子和
阿新 • • 發佈:2021-01-11
題目描述
給定 \(a,b\) ,求 \(a^b\) 的約數之和。
\(1\leq a,b \leq 5\times 10^7\) 。
答案對 \(9907\) 取模。
Solution
先把 \(a\) 分解質因數,假設分解後的柿子是 \(p_1^{a_1}p_2^{a_2}p_3^{a_3}\cdots\cdots p_k^{c_k}\) 。
然後 \(a^b\) 的質因數分解的柿子就是
\[p_1^{a_1\times b}p_2^{a_2\times b}p_3^{a_3\times b}\cdots\cdots p_k^{c_k\times b} \]根據約數求和公式,我們可以得到 \(a^b\)
然後考慮如何求出 \((1+p_i+p_i^2+\cdots+p_i^{a_i\times b})\) 。
方法 1 :分治
為了更加簡便,我們約定這裡要求的柿子是: \((1+p+p^2+\cdots+p^k)\) 。
同時我們約定: \(f(p,k) = (1+p+p^2+\cdots+p^k)\)
這裡分兩種情況討論:
- \(k\) 是奇數,那麼原柿子可以化成:
- \(k\)
注意取模。
完整程式碼如下
#include <cstdio>
#include <cstring>
#define int long long
const int mod = 9901;
inline int pow(int a ,int b) {
int ans = 1;
while (b) {
if (b & 1) ans = ans * a % mod;
a = a * a % mod;
b >>= 1;
}
return ans;
}
inline int f(int p ,int k) {
if (k == 0) return 1;
if (k & 1)
return ((1 + pow(p ,(k + 1) >> 1)) % mod) * f(p ,(k - 1) >> 1) % mod;
return (1 + p * f(p ,k - 1) % mod) % mod;
}
int a ,b ,ans = 1;
signed main() {
scanf("%lld%lld" ,&a ,&b);
if (a == 0) return puts("0") ,0; //這裡記得特判一下 a = 0 ,很坑
for (int i = 2;i * i <= a; i++)
if (a % i == 0) {
int s = 0;
while (a % i == 0) s++ ,a /= i;
ans = ans * f(i ,s * b) % mod;
}
if (a > 1) ans = ans * f(a ,b) % mod;
printf("%lld\n" ,ans);
return 0;
}