[算法竞赛进阶指南] A^B的所有约数之和 (递归)

题目

A^B所有约数之和对9901取模的值。

输入
2 3
输出
15 
解析:
A= p1^k1 *p2^k2 *p3^k *...* pn^kn
A^B= p1^k1B *p2^k2B *p3^k3B *... *pn^knB
  • 因为p1取( p1^0…k1) 都是A^B的约数。
    而( pi^c *pj^d )也是A^B的约数。(所有最简约数的乘积也是他的约数)
    因此A^B的约数之和等于
 (p1^0 +p1^1 +... +pn^k1) * (p2^0 +p2^1 +.... +p2^k2) *... 
 *(pn^0 +pn^1 +... +pn^kn);
  • 计算
  • 当k为奇数时
sum(p,k)= p^0 +p^1 +... +p^k
        =( p^0 +p^1 +...+p^(k/2)) +(p^(k/2+1) +...p^k);
        =( p^0 +p^1 +...+p^(k/2)) +p^(k/2+1) (p^0 +... p^(k/2));
        =( 1+ p^(k/2+1)) *( p^0 +p^1 +... +p^(k/2))
        =(1 +p^(k/2+1)) *sum(p, k/2);
  • 当k为偶数时
sum(p,k)=sum(p,k-1)*p+1    
  • (相当于把指数都减1 然后再乘以p相当于指数加一,再加上p^0=1);
代码:
#include <iostream>
using namespace std;
const int mod=9901;
int A,B; 

int kuaisumi(int p,int k){
	p%=mod;
	int ans=1;
	while(k){
		if(k&1) ans=ans*p%mod;
		p=p*p%mod;
		k>>=1;
	}
	return ans;
}

int sum(int p,int k){
	if(k==0) return 1;
	if(k%2==0) return (p%mod*sum(p,k-1)+1)%mod;
	return (1+kuaisumi(p,k/2+1))*sum(p,k/2)%mod;
}

int main()
{
	cin>>A>>B;
	int ans=1;
	for(int i=2;i<=A;i++){
		int s=0;
		while(A%i==0){
			s++;
			A/=i;
		}
//		cout<<i<<" "<<s<<" "<<B<<endl;
		if(s) ans=ans*sum(i,s*B)%mod;
	} 
	if(A) cout<<ans<<endl;
	else cout<<0<<endl;
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值