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;
}
posted @ 2022-04-03 09:36  zyy2001  阅读(52)  评论(0编辑  收藏  举报