洛谷题单指南-数学基础问题-P1403 [AHOI2005] 约数研究
原题链接:https://www.luogu.com.cn/problem/P1403
题意解读:计算1~n每个数的约数个数之和。
解题思路:
1、数学方法
1~n的约数范围也在1~n,要计算每个数的约数个数之和
可以从约数出发,
比如约数是x,那么在1~n中一共有n/x个数包含x这个约数
x从1一直枚举到n,就可以得出每个约数是多少个数的约数
求和即可
100分代码:
#include <bits/stdc++.h>
using namespace std;
int n;
long long ans;
int main()
{
cin >> n;
for(int i = 1; i <= n; i++) ans += n / i;
cout << ans;
return 0;
}
2、埃氏筛法
数学的方法不太好想!
我们知道:
对于一个数x,分解质因数为x=p1a1*p2a2*...*pnan,则x的约数个数f(x) = (1+a1)*(1+a2)*...*(1+an)
可以用组合数来解释,每个质因数的指数可以取0~ai,也就是1+ai种,乘法原理就可以得到约数的个数。
而埃氏筛法,会用每一个素数去筛包含其为素因子的合数,
这样就可以在埃氏筛的过程中,当用素数i乘以倍数之后得j,在标记j为合数的的同时
也可以计算j一共包含多少个i因子(设为cnt个),然后在f[j]上乘以(1+cnt),就得到素因子i对f[j]的贡献
最后把f[1]~f[n]加起来即可
100分代码:
#include <bits/stdc++.h>
using namespace std;
const int N = 1e6 + 5;
int n;
int f[N], g[N];
bool flag[N];
long long ans;
int main()
{
cin >> n;
for(int i = 1; i <= n; i++) g[i] = i, f[i] = 1;
for(int i = 2; i <= n; i++)
{
if(!flag[i])
{
f[i] = 2; //素数的约数个数是2
for(int j = i + i; j <= n; j += i)
{
flag[j] = true;
int cnt = 0;
while(g[j] % i == 0) cnt++, g[j] /= i; //统计g[j]有多少个i素因子
f[j] = f[j] * (1 + cnt);
}
}
}
for(int i = 1; i <= n; i++) ans += f[i];
cout << ans;
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
· 【杂谈】分布式事务——高大上的无用知识?