洛谷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; }
五、学习价值
通过这个题目可以掌握:
原创内容 转载请注明出处