传送门
题意
给定 (A,B),求 (A^{B}) 的所有约数之和,答案 (mod 9901)
数据范围
(0leq A,Bleq 5 imes 10^{7})
题解
A分解质因数后为
[p_1^{c_{1}} imes p_2^{c_{2}} imes cdots p_n^{c_{n}}
]
[A^{B}=p_1^{c_{1} imes B} imes p_2^{c_2 imes B} imes cdots p_n^{c_n imes B}
]
那么AB的约数之和就是
[(p_1^0+p_1^1+cdots p_1^{c_1 imes B}) imes (p_2^0+p_2^1+cdots p_2^{c_2 imes B}) imes cdots imes (p_n^0+p_n^1+cdots p_n^{c_n* imes })
]
分解质因数后对每一项等比数列求和
每一项的求和公式为:
[frac {1 - p_i^{c_i imes B+1}}{1-p_i}
]
[frac{p_i^{c_i imes B+1}-1}{p_i-1}
]
分母快速幂求得(mod~~9901)的值
因为9901为质数,只要(p_{i-1})不是他的倍数,就互质,根据费马小定理可以求出逆元,
如果是倍数,那么(p_i ~~mod ~~9901)为1
所以等比数列和就是(B imes c_i+1)
Code
#include<bits/stdc++.h>
#define pll pair<long long,long long>
#define ll long long
using namespace std;
const int mod=9901;
pll factor[2000];
int cntf;
ll qmi(ll a,ll k){
ll res=1;
while(k){
if(k&1) res=res*a%mod;
a=a*a%mod;
k>>=1;
}
return res % mod;
}
void get(ll a){
for(ll i=2;i<=a/i;i++){
if(a%i==0){
int num=0;
while(a%i==0){
num++;
a/=i;
}
factor[cntf++]={i,num};
}
}
if(a>1) factor[cntf++]={a,1};
}
int main(){
ll a,b;
cin>>a>>b;
if(a==0)//特判
{
puts("0");
return 0;
}
get(a);
ll ans=1;
for(int i=0;i<cntf;i++){
int p=factor[i].first;
int n=factor[i].second;
if((p-1)%mod ==0){
ans=(ans%mod * (b%mod*n%mod+1)%mod)%mod;
}
else{
ll x=((qmi(p,b*n+1)-1)%mod+mod)%mod;// qmi求得的结果-1后可能为负数
ll y=qmi(p-1,mod-2);
ans=((ans*x)%mod*y)%mod;
}
}
cout<<ans<<endl;
return 0;
}