B - Sumdiv

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;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值