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;
}