Acwing97 约数之和(分治)

题目

数学题,将A分解成质因数相乘的形式,可以得到约数集合,那么约数之和可写成多个等比数列

乘积,接下来问题就是如何求,考虑分治,复杂度O(log)

#include <bits/stdc++.h>
#define ll long long
using namespace std;
const ll P = 9901;
vector<pair<ll, ll> > w;
void fj(ll a) {//分解质因数 
	for (ll i = 2; i * i <= a; i ++)
		if (!(a % i)) {
			ll num = 0;
			while(!(a % i)) num ++, a /= i;
			w.push_back(make_pair(i, num));
		}
	if (a != 1) w.push_back(make_pair(a, 1));
}
ll ksm (ll a, ll b) {//快速幂 
	ll ans = 1;
	for(; b; b >>= 1) {
		if (b & 1) ans = (ans * a) % P;
		a = (a * a) % P; 
	}
	return ans;
}
ll get_sum(ll p, ll c) {//分治等比数列求和 
	if (!p) return 0;
	if (!c) return 1;
	if (c & 1) return (ksm(p, (c + 1) / 2 ) + 1) * get_sum(p, c / 2) % P;//奇数 
	return ((ksm(p, c / 2) + 1) * get_sum(p, c / 2 - 1) + ksm(p, c)) % P;//偶数 
}
int main() {
	ll a, b;
	cin >> a >> b;
	fj(a);
	ll ans = 1;
	for (unsigned ll i = 0; i < w.size(); i ++) {
		ll p = w[i].first, c = w[i].second;
		ans = (ans * get_sum(p, b * c)) % P;
	}
	cout << ans << endl;
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值