原题面:https://vjudge.net/problem/POJ-1845
题目大意:求pow(A,B)的所有约数之和mod9901(1<=A,B<=5e7)。
输入描述:一行两个正整数A(1<=A<=5e7),B(1<=B<=5e7)。
输出描述:输出pow(A,B)所有约数之和mod9901。
样例输入:
2 3
样例输出:
15
分析:把A分解质因数可得A=pow(p1,c1)pow(p2,c2)...pow(pn,cn)。故pow(A,B)的所有约数之和为(1+p1+pow(p1,2)+...+pow(p1,c1))(1+p2+pow(p2,2)+...+pow(p2,c2))...(1+pn+pow(pn,2)+...pow(pn,cn))。可以看出每个部分都是一个等比数列,运用等比数列求和公式即可求出每部分的值,最后相乘取模即为答案。
代码:
#include<bits/stdc++.h> using namespace std; typedef long long ll; const int maxn=40; const ll mod=9901; ll p[maxn],c[maxn],m; void divide(int n) { m = 0; for (int i = 2; i * i <= n; i++) { if (n % i == 0) { p[++m] = i; c[m] = 0; while (n % i == 0) n /= i, c[m]++; } } if (n > 1) p[++m] = n, c[m] = 1; } ll power(ll a,ll b) { ll ret = 1; while (b) { if (b & 1) ret = (ret * a) % mod; a = (a * a) % mod; b >>= 1; } return ret; } ll inv(ll a) { return power(a, mod - 2); } int main() { ll a, b; cin >> a >> b; divide(a); ll ret = 1; for (int k = 1; k <= m; k++) { if ((p[k] - 1 + mod) % mod == 0) { ret = (ret * ((b * c[k] + 1) % mod)) % mod; continue; } ret = (ret * (power(p[k], (ll) b * c[k] + 1) - 1 + mod) % mod) * inv(p[k] - 1) % mod; } cout << ret << endl; return 0; }