进阶指南-----约数之和

又是A^B…现在变成了求约数
都被搞了那么多次,该懂了遇到就要拆,那拆啥,把A拆成约数相乘呗
A =( P1 ^ k1) * (P2 ^ k2 )* …(Pn^kn)
A^B = (P1^(k1 * B)) * (P2^(k2 * B)) * … (Pn^(kn * B))
所以约数组合的和就可以表示为
(1 + P1^1 + P1^2 + P1^3… P1^(k1 * B))* (1 + P2^1 + P2^2 + P2^3… P2^(k2 * B))…(1 + Pn^1 + Pn^2 + Pn^3… Pn^(kn * B))
那么问题就变成了求 (1 + P1^1 + P1^2 + P1^3… P1^(k1 * B))
有人说,哇哦,这不就是传说中的等比数列嘛,直接套公式不就好啦,但是因为要取模,而取模只喜欢+、-、* 不喜欢除法,没办法咯,就只能找合它口味的咯,怎么搞?
分治!妙啊!(n为奇数,因为这个样子才能对半分!0-n有偶数个数!)
sum(p,n) =(1 + P1^1 + P1^2 + P1^3… P1^n )= (1 + P1^1 + P1^2 … P1^(n/2)) + (P1^(n/2 + 1))*(1 + P1^1 + P1^2 … P1^(n/2))
=(1 + P1^(n/2 + 1) ) * (1 + P1^1 + P1^2 … P1^(n/2))
=(1 + P1^(n/2 + 1) ) * sum(p,n/2)
那如果n为偶数咋办,那搞成奇数不就好啦咯
sum(p,n) =(1 + P1^1 + P1^2 + P1^3… P1^n )
= (1 +( P1^0 + P1^1 + P1^2… P1^(n-1) ) *P)
= (1 + P * sum(p,n-1))
然后随便写个快速幂就欧克啦啦啦
代码如下:

#include <cstdio>
using namespace std;
const int  MOD = 9901;
int qmi(int a,int b){
	int res = 1%MOD;
	a%=MOD;
	while(b){
		if(b&1) res = res * a % MOD;
		a = a*a % MOD;
		b >>= 1;
	}
	return res;
}
int sum(int p,int n){
	if(n==0) return 1;
	if(n % 2 == 1) return (1+qmi(p,n/2+1)) % MOD * sum(p,n/2) % MOD;
	return (1+ (p%MOD * sum(p,n-1)% MOD));
}
int main()
{
	int A,B;
	int res = 1;
	scanf("%d%d",&A,&B);
	for (int i = 2; i <= A;i++){
		int s = 0;
		while(A%i==0){
			A/=i;
			s++;
		}
		if(s) res = res* sum(i,s*B) % MOD;
	}
	//因为0不会进入循环 
	if(A == 0) res = 0;
	printf("%d\n",res);
	return 0;
	
 } 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值