97. 约数之和(分治)

Posted Harris-H

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了97. 约数之和(分治)相关的知识,希望对你有一定的参考价值。

97. 约数之和(分治)

a b a^b ab的约数和 模 p p p的值。

σ ( a b ) ( m o d p ) \\large \\sigma(a^b)\\pmod{p} σ(ab)(modp)

首先利用算数基本定理:

a b = ( p 1 k 1 p 2 k 2 … p m k m ) b = p 1 k 1 b p 2 k 2 b … p m k m b \\large a^b=(p_1^{k_1}p_2^{k_2}\\dots p_m^{k_m})^b=p_1^{k_1b}p_2^{k_2b}\\dots p_m^{k_mb} ab=(p1k1p2k2pmkm)b=p1k1bp2k2bpmkmb

σ ( n ) = ( 1 + p 1 + p 1 2 ⋯ + p 1 k 1 ) ( 1 + p 2 + p 2 2 ⋯ + p 2 k 2 ) … ( 1 + p m + p m 2 + ⋯ + p m k m ) = σ ( p 1 k 1 ) σ ( p 2 k 2 ) … σ ( p m k m ) \\sigma(n)=(1+p_1+p_1^2\\dots+p_1^{k_1})(1+p_2+p_2^2\\dots+p_2^{k_2})\\dots (1+p_m+p_m^2+\\dots+ p_m^{k_m})=\\sigma(p_1^{k_1})\\sigma(p_2^{k_2})\\dots \\sigma(p_m^{k_m}) σ(n)=(1+p1+p12+p1k1)(1+p2+p22+p2k2)(1+pm+pm2++pmkm)=σ(p1k1)σ(p2k2)σ(pmkm)

所以我们只需要求出 σ ( p i k i b ) \\large \\sigma(p_i^{k_ib}) σ(pikib)即可。

这个是一个等比数列,有两种方法求解:

1.分治法。

2.公式法。

分治法:令 σ ( p k − 1 ) = f ( p , k ) = p 0 + p 1 + ⋯ + p k − 1 \\sigma(p^{k-1})=f(p,k)=p^0+p^1+\\dots+p^{k-1} σ(pk1)=f(p,k)=p0+p1++pk1

k k k为偶数时:
f ( p , k ) = ( p 0 + p 1 + ⋯ + p k 2 − 1 ) + ( p k 2 + ⋯ + p k − 1 ) = p k 2 ( 1 + f ( a , k 2 ) ) f(p,k)=(p_0+p_1+\\dots+p^{\\small\\dfrac{k}{2}-1})+(p^{\\small\\dfrac{k}{2}}+\\dots+p_{k-1})=p^{\\small\\dfrac{k}{2}}(1+f(a,\\dfrac{k}{2})) f(p,k)=p0+p1++p2k1)+(p2k++pk1)=p2k(1+f(a,2k))

k k k为奇数时,拆掉最后面一项变为偶数情况即可。

代码

// Problem: 约数之和
// Contest: AcWing
// URL: https://www.acwing.com/problem/content/description/99/
// Memory Limit: 64 MB
// Time Limit: 1000 ms
// Date: 2021-07-02 00:16:08
// --------by Herio--------

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull; 
const int N=1e3+5,M=2e4+5,inf=0x3f3f3f3f,mod=9901;
#define mst(a,b) memset(a,b,sizeof a)
#define PII pair<int,int>
#define fi first
#define se second
#define pb emplace_back
#define SZ(a) (int)a.size()
#define ios ios::sync_with_stdio(false),cin.tie(0) 
void Print(int *a,int n){
	for(int i=1;i<n;i++)
		printf("%d ",a[i]);
	printf("%d\\n",a[n]); 
}
vector<PII>v;
void init(int n){
	for(int i=2;i*i<=n;i++)
		if(n%i==0){
			PII x;
			x.fi=i,x.se=0;
			while(n%i==0) x.se++,n/=i;
			v.pb(x);
		}
	if(n>1) v.pb(n,1);
}
ll ksm(ll a,ll n,ll m=mod){
	ll ans=1;
	while(n){
		if(n&1) ans=ans*a%m;
		a=a*a%m;

以上是关于97. 约数之和(分治)的主要内容,如果未能解决你的问题,请参考以下文章

97. 约数之和

算法刷题AcWing 97. 约数之和——递推

97. 约数之和数学 快速幂

《算法竞赛进阶指南》-AcWing-97. 约数之和 Sumdiv-题解

《算法竞赛进阶指南》-AcWing-97. 约数之和 Sumdiv-题解

Sumdiv POJ - 1845 A^b约数之和取模 内部递归 外部分治