题目
定义一个数 的价值为:将这个数分解成若干个正整数 ( 是任意可行正整数)的乘积形式
:。 只能有一个质因子,且对于 ,都满足 ,即两个数互质。
分解之后,这些正整数的和 就是这个数的价值。特殊定义: 的价值是 。
多组询问,每次给定正整数 ,求大小在 范围内的所有数的价值之和。
限制:
算法分析
做法:欧拉筛
使用 ps
数组记录当前已经筛出的质数,使用 val[x]
记录 的价值
原理:欧拉筛中通过 if (i%ps[j] == 0) break;
控制每个合数只能被它的最小质因子标记,使得使得时间复杂度达到线性。
对于质数 :val[i] = i
对于合数 i*ps[j]
有两种情况:
- 的最小质因子大于 ,那么
val[i*ps[j]] = val[i] + ps[j]
- 的最小质因子等于 ,那么先分解出 里面 的最大次幂因子 ,那么
val[i*ps[j]] = val[i] - x + ps[j]*x
然后通过前缀和预处理,每次询问做差分即可。
代码实现
#include <bits/stdc++.h> #define rep(i, n) for (int i = 0; i < (n); ++i) using namespace std; using ll = long long; const int MX = 3e7+5; int ps[MX/10], pf[MX]; ll val[MX]; void init() { int c = 0; for (int i = 2; i < MX; ++i) { if (!pf[i]) ps[++c] = i, pf[i] = i, val[i] = i; for (int j = 1; i*ps[j] < MX; ++j) { if (i%ps[j] == 0) { pf[i*ps[j]] = pf[i]*ps[j]; val[i*ps[j]] = val[i] - pf[i] + pf[i*ps[j]]; break; } else { pf[i*ps[j]] = ps[j]; val[i*ps[j]] = val[i] + ps[j]; } } } for (int i = 1; i < MX; ++i) val[i] += val[i-1]; } int main() { freopen("stupid.in", "r", stdin); freopen("stupid.out", "w", stdout); init(); int t; cin >> t; while (t--) { int l, r; cin >> l >> r; --l; cout << val[r]-val[l] << '\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框架的用法!