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. 约数之和 Sumdiv-题解