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).
The only line contains the two natural numbers A and B, (0 <= A,B <= 50000000)separated by blanks.
The only line of the output will contain S modulo 9901.
2 3
15
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).
The natural divisors of 8 are: 1,2,4,8. Their sum is 15.
15 modulo 9901 is 15 (that should be output).
下面有两种办法求,一种是使用逆元的方法,把除以(p-1)变成×p-1的逆元。但这样是不行的,因为p-1不一定有逆元
第二种方法是把上面的东西转换成多项式相乘的形式,然后用类似于快速幂的分治策略解决
代码:
#include <iostream>
#include <cstdio>
using namespace std;
typedef long long LL;
LL A,B;
LL MOD = 9901;
LL mod_pow(LL x,LL p,LL mod)
{
LL ans = 1;
while(p > 0)
{
if(p & 1)
ans = (x * ans)%mod;
x = (x*x) % mod;
p >>= 1;
}
return (ans + mod )% mod;
}
LL mod_inverse_feima(LL a,LL m)
{
LL ans = mod_pow(a,m-2,m);
return (ans%m+m);
}
int prime[1000];
int prime_cnt[1000];
int cnt = 0;
LL solve(LL x,LL step){
if(step == 0) return 0;
if(step == 1) return 1;
if(step == 2){
return (x + 1)%MOD;
}
if(step%2 == 0){
return (mod_pow(x,step/2,MOD)+1)*solve(x,step/2)%MOD;
}
else{
return solve(x,step-1) + mod_pow(x,step-1,MOD)%MOD;
}
}
void solve2(){
cnt = 0;
LL num = A;
for(int i = 2;i * i <= A;i++){
if(num % i == 0){
prime[cnt] = i;
int e = 0;
while(num % i == 0){
num /= i;
e++;
}
prime_cnt[cnt] = e;
cnt++;
}
}
if(num > 1){
prime[cnt] = num;
prime_cnt[cnt++] = 1;
}
LL ans = 1;
for(int i = 0;i < cnt;i++){
LL tmp = 0;
tmp = (solve(prime[i],prime_cnt[i] * B + 1)) % MOD;
ans = ans * tmp % MOD;
}
printf("%lld\n",ans);
}
int main(){
while(cin>>A>>B){
solve2();
}
return 0;
}