poj1845 Sumdiv

Sumdiv
Time Limit: 1000MS Memory Limit: 30000K
Total Submissions: 15033 Accepted: 3706

Description

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的所有因子之和

解题思路:如果a是素数,我们可以知道a^b的所有因子是1,a,a^2,a^3,...,a^b,

则a^b的所有因子之和为1+a+a^2+a^3+a^4+...+a^b;

如果a不是素数,那么我们可以将a转换为由多个素数组成的合数即a=(p[0]^n[0])*(p[1]^n[1])*(p[2]^n[2])*...*(p[k]^n[k]),(p[0],p[1],p[2],...,p[n]都是素数),

那么a^b转换为p[0]^(n[0]*b) * p[1]^(n[1]*b) * p[2]^(n[2]*b) * ... * p[n]^(n[n]*b),

则所有因子之和为[(1+p[0]+p[0]^2+...+p[0]^(n[0]*b) )*(1+p[1]+p[1]^2+...+p[1]^(n[1]*b) )*...*(1+p[n]+p[n]^2+...+p[n]^(n[n]*b) )

参考代码:

#include <iostream>
#include <stdio.h>
#include <string.h>
typedef long long ll;
using namespace std;
#define m 9901
ll mod_pow(ll a,ll b){	//快速幂
	ll ans=1;
	while (b>0){
		if (b&1)
			ans=ans*a%m;
		a=a*a%m;
		b>>=1;
	}
	return ans;
} 
ll sum(ll p,ll n)  //递归二分求 (1 + p + p^2 + p^3 +...+ p^n)%mod  
{                          //奇数二分式 (1 + p + p^2 +...+ p^(n/2)) * (1 + p^(n/2+1))  
    if(n==0)               //偶数二分式 (1 + p + p^2 +...+ p^(n/2-1)) * (1+p^(n/2+1)) + p^(n/2)  
        return 1;  
    if(n%2)  //n为奇数,  
        return (sum(p,n/2)*(1+mod_pow(p,n/2+1)))%m;  
    else     //n为偶数  
        return (sum(p,n/2-1)*(1+mod_pow(p,n/2+1))+mod_pow(p,n/2))%m;  
} 
/* 
ll sum(ll a,ll b){	//求 1+a^1+a^2+...+a^b的值
	ll ans=mod_pow(a,b+1);
	return (ans-1)/(a-1);
}
*/
int main(){
	int a,b;
	int p[10000],n[10000];	
	while (cin>>a>>b){
		int k=0;
		memset(n,0,sizeof(n));
		for (int i=2;i<=a;i++){	//将a转换为(p[0]^n[0])*(p[1]^n[1])*(p[2]^n[2])*...*(p[k]^n[k])
			if (a%i==0){
				p[k]=i;
				while (a%i==0){
					n[k]++;
					a/=i;
				}
				k++;
			}
		}
		ll ans=1;
		for (int i=0;i<k;i++){
			ans=ans*sum(p[i],b*n[i])%m;
		}
		cout<<ans<<endl;
	}
	return 0;
}




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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值