约数之和
题意:假设现在有两个自然数和 , 是 的所有约数之和。求 mod 的值。
前置知识
由唯一分解定理可得:一个数可以表达成 的形式。 为不同的质数。
设某约数是从第一项中选了 个,第二项中选了 个,... ,第 项中选了 个得到的,那么该约数可以表达为: ;
特别的,当 = = ... = = 0时,约数表示为1。
两个重要的公式
-
约数个数
对每一项
只要选择稍有不同,得到的约数就不一样,不会重复,也不会遗漏。
-
约数之和
为什么上面这个式子可以表示约数的和呢,因为将这个式子每一项展开之后可以得到每一项因子,加起来便为约数和。所以求解约数和就变成了求解括号内的每一个通项。
定义一个函数 ,用来求解每一项 ;
这个式子的求解可以使用递归,在时间复杂度 的情况下求出每一项和,下面是推导过程:
- 如果k是奇数,即该式子有偶数项,那么如下:
问题的规模就从 转换成了 ,递归即可求得;
同时,观察推导式,我们还需要用快速幂求出 。
- 如果k是偶数,有奇数项,那么先套用公式计算出
,即 ,然后将算出的数乘 ,即是 的值,然后加上 ,即1,得解。
#include<bits/stdc++.h>
using namespace std;
#define ll long
const int mod = 9901;
//对于有取模操作的数,x = x * x % mod;
ll getmi(int x, int k) {
x %= mod;
ll res = 1;
while (k) {
if (k & 1) res = (res * x) % mod;
x = (x * x) % mod;
k >>= 1;
}
return res;
}
ll sum(int p, int k) {
if (k == 0) return 1;
if (k & 1) {
return (1 + getmi(p, k / 2 + 1)) * sum(p, k / 2) % mod;
} else {
return (1 + p % mod * sum(p, k - 1)) % mod;
}
}
int main() {
int a, b;
cin >> a >> b;
ll ans = 1;
for (int i = 2; i <= a; i ++) {
int k = 0;
while (a % i == 0) {
k ++;
a /= i;
}
ans = ans * sum(i, k * b) % mod;
}
if (!a) ans = 0;
cout << ans << "\n";
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!