97. 约数之和

Posted acwing_zyy

tags:

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

分治

题目链接

97. 约数之和

假设现在有两个自然数 \\(A\\)\\(B\\)\\(S\\)\\(A^B\\) 的所有约数之和。

请你求出 \\(S\\mod9901\\) 的值是多少。

输入格式

在一行中输入用空格隔开的两个整数 \\(A\\)\\(B\\)

输出格式

输出一个整数,代表 \\(S\\mod9901\\) 的值。

数据范围

\\(0≤A,B≤5×10^7\\)

输入样例:

2 3

输出样例:

15

注意: \\(A\\)\\(B\\) 不会同时为 \\(0\\)

解题思路

分治

先将 \\(a\\) 用算术基本定理表示为 \\(p_1^c_1\\times p_2^c_2\\times \\dots \\times p_n^c_n\\),则 \\(a^b=p_1^b*c_1\\times p_2^b*c_2\\times \\dots \\times p_n^b*c_n\\),其约数之和为 \\((1+p_1+p_1^2+\\dots +p_1^b*c_1)\\times (1+p_2+p_2^2+\\dots +p_2^b*c_2)\\times \\dots \\times (1+p_n+p_n^2+\\dots +p_n^b*c_n)\\),相当于求解 \\(sum(p,c)=1+p+p^2+\\dots + p^c\\)
分情况讨论:

  • \\(n\\) 为奇数,\\(sum(p,c)=sum(p,n/2)+sum(p,c/2)\\times p^n/2+1\\)

  • \\(n\\) 为偶数,\\(sum(p,c)=sum(p,n/2-1)+p^(n/2)\\times sum(p,n/2-1)+p^n\\)

\\(s\\)\\(a\\) 算术基本定理下的幂次之和,则:

  • 时间复杂度:\\(O(loga\\times log(bs))\\)

代码

// Problem: 约数之和
// Contest: AcWing
// URL: https://www.acwing.com/problem/content/99/
// Memory Limit: 64 MB
// Time Limit: 1000 ms
// 
// Powered by CP Editor (https://cpeditor.org)

// %%%Skyqwq
#include <bits/stdc++.h>
 
//#define int long long
#define help cin.tie(NULL); cout.tie(NULL);
#define pb push_back
#define fi first
#define se second
#define mkp make_pair
using namespace std;
 
typedef long long LL;
typedef pair<int, int> PII;
typedef pair<LL, LL> PLL;
 
template <typename T> bool chkMax(T &x, T y)  return (y > x) ? x = y, 1 : 0; 
template <typename T> bool chkMin(T &x, T y)  return (y < x) ? x = y, 1 : 0; 
 
template <typename T> void inline read(T &x) 
    int f = 1; x = 0; char s = getchar();
    while (s < \'0\' || s > \'9\')  if (s == \'-\') f = -1; s = getchar(); 
    while (s <= \'9\' && s >= \'0\') x = x * 10 + (s ^ 48), s = getchar();
    x *= f;


const int mod=9901;
int ksm(int a,int b,int p)

	int res=1%p;
	while(b)
	
		if(b&1)res=1ll*res*a%p;
		a=1ll*a*a%p;
		b>>=1;
	
	return res;

int sum(int p,int c)

	if(c==0)return 1;
	if(c&1)return sum(p,c/2)*(ksm(p,c/2+1,mod)+1)%mod;
	return (sum(p,c/2-1)*(1+ksm(p,c/2,mod))+ksm(p,c,mod))%mod;

int a,b,res=1;
int main()

	cin>>a>>b;
	if(!a)
	
	    cout<<0;
	    return 0;
	
	for(int i=2;i<=a/i;i++)
	
		if(a%i==0)
		
			int cnt=0;
			while(a%i==0)cnt++,a/=i;
			res=res*sum(i,cnt*b)%mod;
		
	
	if(a>1)
		res=res*sum(a,b)%mod;
	cout<<res;
    return 0;

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

AcWing - 97 - 约数之和(分治因数和)

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

97. 约数之和数学 快速幂

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

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

约数之和