【长期】数论题
题单:
注意到当 时,有 。假设当 时值仍然为 ,则有 ,, 且 为整数。
因此,当 时 相等。可以证明,这样的值不超过 个,因此时间复杂度 。
本题考查取模运算的本质。 相当于 ,因此本题式子可以化为:
这同样可以使用整除分块求解,辅以等差数列求和即可,即每次累加
同样地,我们来看 运算的本质。实际上 。不妨设 ,则原式可以化为
我们将前后两部分分别记为 并分开计算:
其中上取整同样可以用整除分块在根号的时间复杂度下计算:
现在需要对 分类讨论。
- 如果 ,那么 ,即直接取到右端点;
- 如果 ,那么
- 否则
将 中 两部分分开计算即可,时间复杂度 。
又
这个式子同样可以用整除分块计算,其中还需要平方和公式的前缀和做差
由于在模意义下计算,需要算出 等的逆元,在不保证模数是质数的情况下使用 exgcd 即可。最后输出时,由于是 ,等价于 (mod - ans%mod) % mod
语句,中途使用正常的 %mod
即可。
inline ll work(ll lim, ll num) { ll res = 0; for(ll l = 1, r = 1; l <= lim; l = r + 1) { ll val = ceil(num * 1.0 / l); if(val == 1) r = lim; else if(num % (val - 1) == 0) r = num / (val - 1) - 1; else r = num / (val - 1); r = min(r, lim); ll sum = ((inv2 * (l + r) % mod) * (r - l + 1) % mod); res = (res + val * sum % mod) % mod; } return res; } inline ll Square(ll x) {return (((inv6 * x % mod) * (x + 1) % mod) * (2 * x + 1)) % mod;} inline ll rSum(ll x, ll y) {return ((Square(y) - Square(x - 1)) % mod + mod) % mod;} inline void solve() { read(T); while(T --) { read(n); read(m); read(mod); if(n > m) n ^= m ^= n ^= m; inv2 = inv(2); inv6 = inv(6); ll ans = 0; ll n2 = ((n % mod) * n % mod), m2 = ((m % mod) * m % mod); ll M1 = ((work(n, n) - n2) % mod + mod) % mod; ll M2 = ((work(m, m) - m2) % mod + mod) % mod; ans = M1 * M2 % mod; ll D = n2 * m % mod; D = ((D - n * work(n, m) % mod) % mod + mod) % mod; D = ((D - m * work(n, n) % mod) % mod + mod) % mod; ll res = 0; for(ll l = 1, r = 1; l <= n; l = r + 1) { ll val1 = ceil(n * 1.0 / l), val2 = ceil(m * 1.0 / l); ll rn = 0, rm = 0; if(val1 == 1) rn = n; else if(n % (val1 - 1) == 0) rn = n / (val1 - 1) - 1; else rn = n / (val1 - 1); if(val2 == 1) rm = n; else if(m % (val2 - 1) == 0) rm = m / (val2 - 1) - 1; else rm = m / (val2 - 1); rm = min(rm, n); r = min(rn, rm); ll sum = rSum(l, r); res = (res + (val1 * val2 % mod) * sum % mod) % mod; } D = (D + res) % mod; ans = ((ans - D) % mod + mod) % mod; ans = (mod - ans) % mod; writeln(ans); } }
P3935 约数个数和
题目中的 表示约数个数,因此此题求得是
枚举约数,并利用前缀和做差计算区间和即可,因此下面计算前缀和。
用整除分块计算即可,时间复杂度
转化成平面直角坐标系,除了 两个点之外,其余点 有连线当且仅当 ,否则会被点 挡住。
因此,答案为
这道题是一道筛法练习题。
题目中要求 ,定义 表示去重前 的质因数个数, 表示 的最小质因数大小,即 。
这两个函数都可以在线性筛的时候计算,其中
这样计算出 的问题在于当 时 ,所以判断的条件是
inline void init(int MAX) { vis[1] = vis[0] = 1; tau[1] = 1, w[1] = lpf[1] = 0; rep(i, 2, MAX) { if(!vis[i]) prime[++cnt] = i, tau[i] = 2, w[i] = 1, lpf[i] = i; for(int j = 1; j <= cnt && i * prime[j] <= MAX; j ++) { w[i * prime[j]] = w[i] + 1; vis[i * prime[j]] = 1; lpf[i * prime[j]] = min(lpf[i], prime[j]); if(i % prime[j] == 0) { tau[i * prime[j]] = tau[i] * 2 - tau[i / prime[j]]; break; } tau[i * prime[j]] = tau[i] * 2; } } } int main () { init(1000000), int k = 0; rep(i, 1, 1000000) { if(w[tau[i]] == 2 && tau[i] != lpf[tau[i]] * lpf[tau[i]]) if(++k == 9) k = 0, writeln(i); } return 0; }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· 三行代码完成国际化适配,妙~啊~
· .NET Core 中如何实现缓存的预热?