小M的因子和
时间限制:1000 ms | 内存限制:65535 KB
难度:2
- 描述
-
小M在上课时有些得意忘形,老师想出道题目难住他。小M听说是求因子和,还是非常得意,但是看完题目是求A的B次方的因子和,有些手足无措了,你能解决这个问题吗?- 输入
- 有多组测试样例
每行两个数 A ,B ,(1≤A,B≤10^9)
- 输出
- 输出A的B次方的因子和,并对9901取余。
- 样例输入
-
2 3
- 样例输出
-
15
分析:对A进行质因数分解,假设A = (p1^a1) * (p2^a2)*……*(pk^ak),假设A的因子和为sum,
则sum=(1 + p1 + p1^2 + ……+p1^a1)*(1+p2+p2^2 + ……+p2^a2)*……*(1+pk+pk^2+……+pk^ak),把这个式子展开之后.每一项刚好是A的因子。
所以求A^B的因子和时,只需把ai 改为ai*b,然后再求解即可。求得时候因为次方比较大,要用分治和快速幂来求。
#include <cstdio> #include <cmath> const int mod = 9901; int Pow(int a, int n) { //快速幂求a^n int res = 1; a %= mod; while(n) { if(n&1) res = res * a % mod; a = a * a % mod; n >>= 1; } return res; } int get_sum(int a, int n) { //求(1 + a + a^2 + …… + a^n) if(n == 0) return 1; if(n&1) return get_sum(a, n / 2) * (Pow(a, (n / 2 + 1)) + 1) % mod; else return (get_sum(a, n / 2 - 1) * (Pow(a, n / 2) + 1) + Pow(a, n)) % mod; } int main() { int a, b; while(~scanf("%d%d", &a, &b)) { int ans = 1; int m = (int)sqrt(a + 0.5); for(int i = 2; i <= m; ++i) { if(a % i == 0) { int k = 0; while(a % i == 0) { k++; a /= i; } ans = ans * get_sum(i, k * b) % mod; } } if(a > 1) ans = ans * get_sum(a, b) % mod; printf("%d\n", ans); } return 0; }
时间: 2024-10-07 23:48:40