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).
Input
The only line contains the two natural numbers A and B, (0 <= A,B <= 50000000)separated by blanks.
Output
The only line of the output will contain S modulo 9901.
Sample Input
2 3
Sample Output
15
Hint
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).
题意:给两个自然数A,B,S=A^B,求S的所有因数的和
原代码超时:在循环中判断i是否是A的因数时,用自己写函数is_prime判断是否是质数,实际上没有必要,2、3、5、7等这些质数被A完全除去后,它们的公倍数就不会被A整除
原代码:
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cmath>
#include<map>
using namespace std;
typedef long long ll;
const int MAX = 1e5;
const int mod = 9901;
ll pow(ll p,ll c){
ll ans=1;
for(;c;c/=2){
if(c%2!=0){
ans = (ll) ans * p % mod;
}
p = (ll) p * p % mod;
}
return ans;
}
map<int,int> prime_factor;
ll sum(ll p,ll c){
if(c==0) return 1;
ll ans;
if(c%2!=0){
ans=(1+pow(p,(c+1)/2))%mod*sum(p,(c-1)/2)%mod;
ans%=mod;
}
else{
ans=(1+pow(p,c/2))%mod*sum(p,c/2-1)%mod+pow(p,c)%mod;
ans%=mod;
}
return ans;
}
int main(){
int A,B,temp;
scanf("%d%d",&A,&B);
temp=A;
for(int i=2;i*i<=temp;){
if(temp%i==0){
while(temp%i==0){
prime_factor[i]++;
temp/=i;
}
}
if(i!=2) i+=2;
else i+=1;
}
if(temp!=1) prime_factor[temp]=1;
map<int,int>::iterator it=prime_factor.begin();
ll ans=1;
for(;it!=prime_factor.end();it++){
ans*=sum(it->first,(ll)it->second*B);
ans%=mod;
}
printf("%lld\n",ans);
return 0;
}
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cmath>
#include<map>
using namespace std;
typedef long long ll;
const int MAX = 1e5;
const int mod = 9901;
ll pow(ll p,ll c){
ll ans=1;
for(;c;c/=2){
if(c%2!=0){
ans = (ll) ans * p % mod;
}
p = (ll) p * p % mod;
}
return ans;
}
map<int,int> prime_factor;
ll sum(ll p,ll c){
if(c==0) return 1;
ll ans;
if(c%2!=0){
ans=(1+pow(p,(c+1)/2))%mod*sum(p,(c-1)/2)%mod;
ans%=mod;
}
else{
ans=(1+pow(p,c/2))%mod*sum(p,c/2-1)%mod+pow(p,c)%mod;
ans%=mod;
}
return ans;
}
int main(){
int A,B,temp;
scanf("%d%d",&A,&B);
temp=A;
for(int i=2;i*i<=temp;){
if(temp%i==0){
while(temp%i==0){
prime_factor[i]++;
temp/=i;
}
}
if(i!=2) i+=2;
else i+=1;
}
if(temp!=1) prime_factor[temp]=1;
map<int,int>::iterator it=prime_factor.begin();
ll ans=1;
for(;it!=prime_factor.end();it++){
ans*=sum(it->first,(ll)it->second*B);
ans%=mod;
}
printf("%lld\n",ans);
return 0;
}