对于一个数x,假设他分解质因数后的形式为p1a1 *p2a2 *p3a3 。则他的约数之和为(1+p1+···+p1a1)*(1+p2+···+p2a2)*(1+p3+···+p3a3)。
故本题只需要将A分解质因数,每个质因子的数量乘以B。再按照上式计算即可。
如何计算呢,我们可以依次计算每个质因子,最后相乘。但是由于A分解质因数后需要乘以B,可能会使次数很大,所以我们无法一次一次的循环。
考虑分治,对于每一个质因子,令sum(p,k)=(1+p+···+pk):
如果k是偶数,则sum(p,k)=(1+p+···+pk/2-1)+pk/2+(pk/2+1+···pk)=(1+p+···+pk/2-1)+pk/2+pk/2+1 *(1+p+···+pk/2-1)=sum(p,k/2-1)(1+pk/2+1)+pk/2 。
如果k是奇数,类似的sum(p,k)=sum(p,k/2)*(1+k/2+1)。
这样就将O(k)优化到了O(logk)轻松通过。
代码:
#include<bits/stdc++.h>
using namespace std;
const int mod = 9901;
typedef pair<int, int> PII;
int a,b;
int qmi(int a,int b,int p){
a%=p;
int res=1;
while(b){
if(b&1)res=res*a%p;
b>>=1;
a=a*a%p;
}
return res;
}
int sum(int p,int k){
if(k==0)return 1;
if(k&1)return sum(p,k/2)*(1+qmi(p,k/2+1,mod))%mod;
return ((qmi(p,k/2+1,mod)+1)*sum(p,k/2-1)%mod+qmi(p,k/2,mod))%mod;
}
int main(){
cin>>a>>b;
if(a==0){
cout<<0;
return 0;
}
vector<PII>primes;
for(int i=2;i<=a&&a>1;i++){
if(a%i==0){
int cnt=0;
while(a%i==0){
cnt++;
a/=i;
}
if(b)primes.push_back({i,cnt*b});
}
}
if(a>1&&b)primes.push_back({a,b});
int res=1;
for(auto [p,k]:primes){
res=res*sum(p,k)%mod;
}
cout<<res;
return 0;
}