Description
Consider two natural numbers A and B. Let S be the sum of all natural divisors of A^B. Determine S modulo 9901 (the rest of the division of S by 9901).
Input
The only line contains the two natural numbers A and B, (0 <= A,B <= 50000000)separated by blanks.
Output
The only line of the output will contain S modulo 9901.
Sample Input
2 3
Sample Output
15
Hint
2^3 = 8.
The natural divisors of 8 are: 1,2,4,8. Their sum is 15.
15 modulo 9901 is 15 (that should be output).
题目大意:
求
A
B
A^B
AB的所有约数之和mod 9901
解析:
根据算数基本定理“约数和”推论,N的所有正约数的和=
∏
i
=
1
m
(
∑
j
=
0
c
i
(
p
i
)
j
)
\prod _{i=1}^m(\sum_{j=0}^{c_i} (p_i)^j)
∏i=1m(∑j=0ci(pi)j)
式中,每一项都是一个等比数列,如第一项
1
+
p
1
+
p
1
2
+
.
.
.
+
p
1
B
∗
C
1
=
p
1
B
∗
C
1
+
1
−
1
p
1
−
1
1+p_1 + p_1^2 + ... + p_1^{B*C_1} = \frac {p_1^{B*C_1+1}-1}{p_1-1}
1+p1+p12+...+p1B∗C1=p1−1p1B∗C1+1−1
分子用快速幂计算
除分母变为乘分母逆元,用费马小定理求
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
typedef long long ll;
int a, b, m, ans = 1, mod = 9901;
int p[20], c[20];
// 把n质因数分解,p和c分别放在数组中
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;
}
// 快速幂
int power(int a, ll b)
{
int c = 1;
for (; b; b >>= 1)
{
if (b & 1)
c = (ll)c * a % mod;
a = (ll)a * a % mod;
}
return c;
}
int main()
{
cin >> a >> b;
divide(a); // 分解质因数
for (int i = 1; i <= m; i++)
{
if ((p[i] - 1) % mod == 0)
{ // 没有逆元,特判
ans = ((ll)b * c[i] + 1) % mod * ans % mod;
continue;
}
int x = power(p[i], (ll)b * c[i] + 1); // 分子
x = (x - 1 + mod) % mod;
int y = p[i] - 1; // 分母
y = power(y, mod - 2); // 费马小定理
ans = (ll)ans * x % mod * y % mod;
}
cout << ans << endl;
return 0;
}