一道把很多东西放在一起的练手题。

$$\sum_{i = A}^{B}\sum_{j = 1}^{i}\left \{ \frac{i}{j} \right \} = \sum_{i = A}^{B}\sum_{j = 1}^{i}\frac{n - \left [ \frac{n}{j}\right] * j}{i} = \sum_{i = A}^{B}(i * \sum_{j = 1}^{i}inv(j) - \sum_{j = 1}^{i}\left \lfloor \frac{n}{j} \right \rfloor)$$

这样子把里面的$(i * \sum_{j = 1}^{i}inv(j) - \sum_{j = 1}^{i}\left \lfloor \frac{n}{j} \right \rfloor)$算出来做个前缀和就好了。

前面的那个东西可以$O(n)$递推然后前缀和算出来,而后面的那个东西其实就是$\sum_{i = 1}^{n}d(i)$($d(i)$表示$i$的约数个数)。

证明:

$$\sum_{i = 1}^{n}d(i) = \sum_{i = 1}^{n}\sum_{j = 1}^{i}\left [ j| i\right] = \sum_{j = 1}^{n}\sum_{i = 1}^{n}\left [ j| i\right] = \sum_{i = 1}^{n}\left \lfloor \frac{n}{i} \right \rfloor$$

这样子线性筛之后前缀和就做完了。

记得数组开少一点……我就是这样MLE了一次。

时间复杂度$O(n)$。

Code:

#include <cstdio>
#include <cstring>
using namespace std;
typedef long long ll; const int N = 1e6 + ;
const int Maxn = 1e6;
const ll P = 998244353LL; int testCase, pCnt = , pri[N], low[N];
ll inv[N], d[N], h[N];
bool np[N]; template <typename T>
inline void read(T &X) {
X = ; char ch = ; T op = ;
for(; ch > '' || ch < ''; ch = getchar())
if(ch == '-') op = -;
for(; ch >= '' && ch <= ''; ch = getchar())
X = (X << ) + (X << ) + ch - ;
X *= op;
} template <typename T>
inline void inc(T &x, T y) {
x += y;
if(x >= P) x -= P;
} inline void sieve() {
d[] = ;
for(int i = ; i <= Maxn; i++) {
if(!np[i])
pri[++pCnt] = i, low[i] = i, d[i] = ;
for(int j = ; i * pri[j] <= Maxn && j <= pCnt; j++) {
np[i * pri[j]] = ;
if(i % pri[j] == ) {
low[i * pri[j]] = pri[j] * low[i];
if(low[i] == i) d[i * pri[j]] = d[i] + ;
else d[i * pri[j]] = d[i / low[i]] * d[pri[j] * low[i]];
break;
}
low[i * pri[j]] = pri[j];
d[i * pri[j]] = d[i] * d[pri[j]];
}
} for(int i = ; i <= Maxn; i++) inc(d[i], d[i - ]);
} int main() {
sieve();
inv[] = 1LL;
for(int i = ; i <= Maxn; i++) inv[i] = inv[P % i] * (P - P / i) % P;
for(int i = ; i <= Maxn; i++) inc(inv[i], inv[i - ]); for(int i = ; i <= Maxn; i++) h[i] = (1LL * i * inv[i] % P - d[i] + P) % P;
for(int i = ; i <= Maxn; i++) inc(h[i], h[i - ]); read(testCase);
for(int l, r; testCase--; ) {
read(l), read(r);
printf("%lld\n", (h[r] - h[l - ] + P) % P);
} return ;
}

最新文章

  1. JS实现继承的几种方式
  2. DIV未知宽度高度垂直水平居中
  3. SHOI 2009 会场预约 平衡树 STL练习
  4. java线程池
  5. 线性空间光照(即Gamma)
  6. 《zw版&#183;Halcon-delphi系列原创教程》halconxlib控件列表
  7. Arduino语言学习记录(持续更新)
  8. weblogic启动报错之Unrecognized option: -jrockit
  9. SVN官方版本下载地址
  10. 关于MS12-020一次简单尝试
  11. 运用socket实现简单的ssh功能
  12. 用python-webdriver实现自动填表
  13. SQL 约束 (Constraints)
  14. switch case 遇到判断type分支的写法
  15. 给iPhone手机安装*.ipa
  16. linux配置无秘钥登陆
  17. 〖Linux〗Kubuntu 14.04的Eclipse 崩溃解决方法总结
  18. winform窗体 控件 【ListView】
  19. 【ActiveMQ】- 发布/订阅模式
  20. 什么是集群(Cluster)技术

热门文章

  1. Hexo博客网站再配置
  2. fn project 运行时配置选项
  3. 非常好用的css代码格式化工具
  4. 2 分支语句——《Swift3.0 从入门到出家》
  5. unittest框架,调用函数类 和 调用函数外的 方法
  6. HDU 1878 欧拉回路(无向图的欧拉回路)
  7. 小程序中WXSS样式控制
  8. PL/SQL 训练10--io及文件操作
  9. 第一章 为什么使用NoSQL
  10. linux 输入子系统之电阻式触摸屏驱动