算法思路:
使用分治法求$sum(p, c) = 1 + p + p^2 + … + p^c$
当c为奇数时:
$$sum(p, c) = (1 + p + … + p^{\frac{c - 1}{2}}) + (p^{\frac{c + 1}{2}} + … + p^c) \\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ = (1 + p + … + p^{\frac{c - 1}{2}}) + p^{\frac{c + 1}{2}} * (1 + p + … + p^{\frac{c - 1}{2}})\\ 同时提取出(1 + p + … + p^{\frac{c - 1}{2}}),得: (1 + p^{\frac{c + 1}{2}}) * sum(p, \frac{c - 1}{2})$$当c为偶数时:
$$sum(p, c) = (1 + p + … + p^{\frac{c}{2} - 1}) + (p^{\frac{c}{2}} + … + p^c) \\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ = (1 + p + … + p^{\frac{c}{2} - 1}) + p^{\frac{c}{2}} * (1 + p + … + p^{\frac{c - 1}{2}}) + p^c\\ = (1 + p^{\frac{c}{2}}) * sum(p, \frac{c}{2} - 1) + p^c $$搭配快速幂对p的次幂求解即可。
整体步骤如下:
1. 将A
分解成质因数,假设某一个质因数的个数为c
2. 分治法分别求每一层$(1 + p + p^2 + … + p^{b * c})$
3. 将返回的计算结果乘上最终结果ans
并mod
#include <iostream>
using namespace std;
#include <cstring>
#include <vector>
const static int N = 5e7+10, MOD = 9901;
int a, b;
using PII = pair<int, int>;
using ULL = unsigned long long;
vector<PII> primes;
void get_primes()
{
for(int i = 2; i <= a / i; ++i)
{
if(a % i == 0)
{
int cnt = 0;
while(a % i == 0)
{
++cnt;
a /= i;
}
primes.push_back({i, cnt});
}
}
if(a > 1)
{
primes.push_back({a, 1});
}
}
ULL qmi(int p, int k)
{
ULL ans = 1;
while(k)
{
if(k & 1) ans = (ans % MOD * p);
p = p % MOD * p % MOD; // 不能保证 p * p 一定不会溢出,所以要两次mod,否则答案错误。
k >>= 1;
}
return ans;
}
ULL sum(int p, int c)
{
// 递归终止条件必不可少
if(c == 0)
return 1;
if(c % 2) // 奇数次幂
return ((1 + qmi(p, (c + 1) / 2)) * sum(p, (c - 1) / 2)) % MOD;
else
return ((1 + qmi(p, c / 2)) * sum(p, c / 2 - 1) + qmi(p, c)) % MOD;
}
int main()
{
cin >> a >> b;
get_primes();
ULL ans = 1;
for(int i = 0; i < primes.size(); ++i)
{
int p = primes[i].first, c = primes[i]. second;
ans = ans * sum(p, c * b) % MOD;
}
// 特判,出题人险恶啊
if(a == 0)
cout << 0 << endl;
else
cout << ans << endl;
}