题目链接
http://poj.org/problem?id=1845
分析
将 AAA 分解质因数为 p1c1∗p2c2∗...∗pncnp_1 ^ {c_1} * p_2 ^ {c_2} * ... * p_n ^ {c_n}p1c1∗p2c2∗...∗pncn,
则 ABA ^ BAB 为 p1B∗c1∗p2B∗c2∗...∗pnB∗cnp_1 ^ {B * c_1} * p_2 ^ {B * c_2} * ... * p_n ^ {B * c_n}p1B∗c1∗p2B∗c2∗...∗pnB∗cn,
其约数之和为 (1+p1+p12+...+p1B∗c1)∗(1+p2+p22+...+p2B∗c2)∗...∗(1+pn+pn2+...+pnB∗cn)(1 + p_1 + p_1 ^ 2 + ... + p_1 ^ {B * c_1}) * (1 + p_2 + p_2 ^ 2 + ... + p_2 ^ {B * c_2}) * ... * (1 + p_n + p_n ^ 2 + ... + p_n ^ {B * c_n})(1+p1+p12+...+p1B∗c1)∗(1+p2+p22+...+p2B∗c2)∗...∗(1+pn+pn2+...+pnB∗cn),
接下来是如何快速求 1+p+p2+...+pc1 + p + p ^ 2 + ... + p ^ c1+p+p2+...+pc,显然使用等比数列求和公式是行不通的,可以利用分治思想:
若 ccc 为奇数,则其等于 ((1+pc+12)∗(1+p+p2+...+pc−12)((1 + p ^ {\frac{c + 1}{2}}) * (1 + p + p ^ 2 + ... + p ^ {\frac{c - 1}{2}})((1+p2c+1)∗(1+p+p2+...+p2c−1),
若 ccc 为偶数,则其等于 (1+pc2)∗(1+p+p2+pc2−1)+pc(1 + p ^ {\frac{c}{2}}) * (1 + p + p ^ 2 + p ^ {\frac{c}{2} - 1}) + p ^ c(1+p2c)∗(1+p+p2+p2c−1)+pc
AC代码
#include <cstdio>
inline int read() {
int num = 0;
char c = getchar();
while (c < '0' || c > '9') c = getchar();
while (c >= '0' && c <= '9')
num = num * 10 + c - '0', c = getchar();
return num;
}
const int mod = 9901;
inline int qpow(int a, int b) {
int ans = 1, x = a % mod;
while (b) {
if (b & 1) ans = ans * x % mod;
x = x * x % mod, b >>= 1;
}
return ans;
}
inline int sum(int p, int q) {
if (!q) return 1;
if (q & 1) return (1 + qpow(p, q / 2 + 1)) * sum(p, q / 2) % mod;
else return (sum(p, q - 1) + qpow(p, q)) % mod;
}
int main() {
int a = read(), b = read(), ans = 1;
if (a < 2) printf("%d", a);
else {
for (int i = 2; i * i <= a; ++i)
if (a % i == 0) {
int cnt = 0;
while (a % i == 0) a /= i, ++cnt;
ans = ans * sum(i, cnt * b) % mod;
}
if (a > 1) ans = ans * sum(a, b) % mod;
printf("%d", ans);
}
return 0;
}