洛谷P1593:深入理解因子和计算,从数学原理到算法实现
一、问题本质分析
题目要求计算a^b的所有因子之和,并对结果取模9901。关键在于理解:
二、核心算法思想
质因数分解:将a分解为质因数的乘积形式
等比数列求和:对于每个质因数p,计算1 + p + p^2 + ... + p^(e*b)
三、关键技术点详解
质因数分解:
从2开始试除,分解a的质因数
记录每个质因数的指数
时间复杂度O(√a)
等比数列求和公式:
对于质因数p,其贡献为(1 + p + p^2 + ... + p^(e*b))
使用分治方法递归计算,避免数值溢出
公式推导:S(n) = (1 + p^(n/2)) * S(n/2-1) + p^n (n为偶数)
快速幂算法:
通过二进制分解指数加速计算
每次将指数减半,平方底数
时间复杂度O(log n)
四、代码实现
#include <iostream>
#include <vector>
#include <cmath>
using namespace std;
const int MOD = 9901;
// 快速幂计算 (base^exp) % MOD
long long qpow(long long base, long long exp) {
long long res = 1;
while (exp) {
if (exp & 1) res = res * base % MOD;
base = base * base % MOD;
exp >>= 1;
}
return res;
}
// 计算等比数列和 (1 + p + p^2 + ... + p^e) % MOD
long long sum(long long p, long long e) {
if (e == 0) return 1;
if (p == 0) return 0;
if (e % 2 == 1) {
return (1 + qpow(p, (e+1)/2)) * sum(p, (e-1)/2) % MOD;
} else {
return ((1 + qpow(p, e/2)) * sum(p, e/2-1) + qpow(p, e)) % MOD;
}
}
int main() {
int a, b;
cin >> a >> b;
if (a == 0) {
cout << 0 << endl;
return 0;
}
int res = 1;
// 质因数分解
for (int i = 2; i*i <= a; i++) {
if (a % i == 0) {
int cnt = 0;
while (a % i == 0) {
a /= i;
cnt++;
}
res = res * sum(i, cnt * b) % MOD;
}
}
if (a > 1) {
res = res * sum(a, b) % MOD;
}
cout << res << endl;
return 0;
}五、学习价值
通过这个题目可以掌握:
原创内容 转载请注明出处

