题目大意:$n(n\leqslant10^6)$组询问,每组询问给出$l,r(l,r\leqslant10^6)$,求($\{\dfrac ij\}$表示$\dfrac ij$的小数部分):
$$
\sum\limits_{i=l}^r\sum\limits_{j=1}^i\{\dfrac ij\}\pmod{998244353}
$$
题解:令$f(x)=\sum\limits_{i=1}^x\{\dfrac xi\}$
$$
f(x+1)=\sum\limits_{i=1}^{x+1}\{\dfrac{x+1}i\}\\
f(x+1)=\sum\limits_{i=1}^{x+1}\{\dfrac xi+\dfrac 1i\}\\
\because \{\dfrac{x+1}{x+1}\}=0\\
\therefore f(x+1)=f(x)+\sum\limits_{i=1}^{x}\{\dfrac 1i\}-\sum\limits_{i=1}^{x+1}[\{\dfrac{x+1}i\}=0]+1\\
令s_0(x)为x的约数个数\\
即f(x+1)=f(x)+\sum\limits_{i=1}^{x}\{\dfrac 1i\}-s_0(x+1)+1
$$
求几次前缀和即可
卡点:无
C++ Code:
#include <cstdio> #include <iostream> #define maxn 1000005 const int mod = 998244353; inline void reduce(int &x) { x += x >> 31 & mod; } inline int getreduce(int x) { return x + (x >> 31 & mod); } int n; int inv[maxn], sinv[maxn], f[maxn]; int ans[maxn], sans[maxn]; int main() { std::ios::sync_with_stdio(false), std::cin.tie(0), std::cout.tie(0); inv[1] = sinv[1] = 1; for (int i = 2; i < maxn; ++i) { inv[i] = static_cast<long long> (mod - mod / i) * inv[mod % i] % mod; reduce(sinv[i] = sinv[i - 1] + inv[i] - mod); } for (int i = 2; i < maxn; ++i) for (int j = i; j < maxn; j += i) ++f[j]; for (int i = 2; i < maxn; ++i) { reduce(ans[i] = ans[i - 1] + sinv[i - 1] - mod); reduce(ans[i] -= f[i]); reduce(sans[i] = sans[i - 1] + ans[i] - mod); } std::cin >> n; while (n --> 0) { static int l, r; std::cin >> l >> r; std::cout << getreduce(sans[r] - sans[l - 1]) << '\n'; } return 0; }