题目描述
假设现在有两个自然数 A 和 B,S 是 A B A^B AB 的所有约数之和。
请你求出 S mod 9901的值是多少。
输入格式
在一行中输入用空格隔开的两个整数 A 和 B 。
输出格式
输出一个整数,代表 S mod 9901 的值。
数据范围
0 ≤ A , B ≤ 5 × 1 0 7 0≤A,B≤5\times10^7 0≤A,B≤5×107
输入样例:
2 3
输出样例:
15
解题思路
本题目需要知道一定的数学知识。
假定 A B = ( p 1 t 1 × p 2 t 2 × … … × p n t n ) B = p 1 t 1 B × p 2 t 2 B × … … × p n t n B = p 1 k 1 × p 2 k 2 × … … × p n k n ( k i = t i B ; p i ∈ 质 数 ) A^B = (p_1^{t_1} \times p_2^{t_2} \times …… \times p_n^{t_n})^B = p_1^{t_1B} \times p_2^{t_2B} \times …… \times p_n^{t_nB} = p_1^{k_1} \times p_2^{k_2} \times …… \times p_n^{k_n} (k_i = t_iB ; p_i \in 质数) AB=(p1t1×p2t2×……×pntn)B=p1t1B×p2t2B×……×pntnB=p1k1×p2k2×……×pnkn(ki=tiB;pi∈质数) 。
A 的约数(因子)一定是若干 p i p_i pi 的任意搭配。因此可以得知,约数数量为 ( k 1 + 1 ) × ( k 2 + 1 ) × … … × ( k n + 1 ) (k_1 + 1) \times (k_2 + 1) \times ……\times (k_n + 1) (k1+1)×(k2+1)×……×(kn+1)
所有约数之和为 ( p 1 0 + p 1 1 + … … + p 1 k 1 ) × ( p 2 0 + p 2 1 + … … + p 2 k 2 ) × … … × ( p n 0 + p n 1 + … … + p n k n ) (p_1^0 + p_1^1 + …… + p_1^{k_1}) \times (p_2^0 + p_2^1 + …… + p_2^{k_2}) \times …… \times (p_n^0 + p_n^1 + …… + p_n^{k_n}) (p10+p11+……+p1k1)×(p20+p21+……+p2k2)×……×(pn0+pn1+……+pnkn)
那么现在问题就是如何求解 s u m ( p 1 , k ) = p 1 0 + p 1 1 + … … + p 1 k 1 sum(p_1,k) = p_1^0 + p_1^1 + …… + p_1^{k_1} sum(p1,k)=p10+p11+……+p1k1 。
一种方式是直接使用等比数列求和公式。另外一种方式则是使用递归进行解决。
这里介绍一下如何进行递归解决。
当 k 为奇数时,总共有偶数项求和。
s u m ( p 1 , k ) = p 1 0 + p 1 1 + … … + p 1 k 1 = p 1 0 + p 1 1 + … … + p 1 k / 2 + p 1 k / 2 + 1 + … … + p 1 k sum(p_1,k) = p_1^0 + p_1^1 + …… + p_1^{k_1} = p_1^0 + p_1^1 + …… + p_1^{k/2} + p_1^{k/2 + 1} + …… + p_1^k sum(p1,k)=p10+p11+……+p1k1=p10+p11+……+p1k/2+p1k/2+1+……+p1k
= p 1 0 + p 1 1 + … … + p 1 k / 2 + p 1 k / 2 + 1 ( p 1 0 + … … + p 1 k / 2 ) = p_1^0 + p_1^1 + …… + p_1^{k/2} + p_1^{k/2 + 1}(p_1^0 + …… + p_1^{k/2}) =p10+p11+……+p1k/2+p1k/2+1(p10+……+p1k/2)
= ( p 1 0 + p 1 1 + … … + p 1 k / 2 ) × ( 1 + p 1 k / 2 + 1 ) = (p_1^0 + p_1^1 + …… + p_1^{k/2}) \times (1 + p_1^{k/2 + 1}) =(p10+p11+……+p1k/2)×(1+p1k/2+1)
这样就出现了递归。
当 k 为偶数时,总共有奇数项。
s u m ( p 1 , k ) = p 1 0 + p 1 1 + … … + p 1 k 1 = 1 + p 1 ( p 1 0 + p 1 1 + … … + p 1 k − 1 ) sum(p_1,k) = p_1^0 + p_1^1 + …… + p_1^{k_1} = 1 + p_1(p_1^0 + p_1^1 + …… + p_1^{k - 1}) sum(p1,k)=p10+p11+……+p1k1=1+p1(p10+p11+……+p1k−1)
这样就将奇数项转换为了偶数项。
#include <iostream>
using namespace std;
const int mod = 9901;
// 快速幂乘求解 (x^k)%p
int quickmul(int x,int k,int p)
{
x = x % mod;
int res = 1,t = x;
while(k)
{
if(k & 1)
{
res = (res * t) % p;
}
k = k >> 1;
t = (t * t) % p;
}
return res;
}
int sum(int p,int k)
{
if(k == 0)
{
return 1;
}
if(k & 1)
{
return ((1 + quickmul(p,k / 2 + 1,mod)) * sum(p,k / 2)) % mod;
}
else
{
return (1 + p % mod * sum(p,k - 1)) % mod;
}
}
int main()
{
int A,B;
int s,result = 1;
cin >> A >> B;
for(int i = 2;i <= A;i++)
{
s = 0;
while(A % i == 0)
{
s++;
A = A / i;
}
if(s)
{
result = result * sum(i,s * B) % mod;
}
}
// 题目中说A,B不会同时为0,B是否为0,sum函数都可以解决,但是A为0需要单独说明
if(!A)
{
result = 0;
}
cout << result << endl;
return 0;
}