传送门
解析:
首先这个结论要知道,不知道就记住,很简单的组合数学推理:
对于一个数 n = ∏ i = 1 t p i k i n=\prod_{i=1}^tp_i^{k_i} n=∏i=1tpiki,它的因数个数是 d ( n ) = ∏ i = 1 t ( k i + 1 ) d(n)=\prod_{i=1}^t(k_i+1) d(n)=∏i=1t(ki+1),就是考虑每个质因子出现0~ k i k_i ki次,一共 k i + 1 k_i+1 ki+1种方案。
所以题目中: f = d f=d f=d
考虑差分,设 S ( n ) = ∑ i = 1 n d ( i ) S(n)=\sum_{i=1}^{n}d(i) S(n)=∑i=1nd(i),那么询问的就是 S ( r ) − S ( l − 1 ) S(r)-S(l-1) S(r)−S(l−1)
考虑如何计算 S S S:
我们有如下结论: S ( n ) = ∑ i = 1 n ⌊ n i ⌋ S(n)=\sum_{i=1}^{n}\lfloor\frac{n}i\rfloor S(n)=i=1∑n⌊in⌋
怎么理解?我们要统计每个数的约数个数,等价于统计每个数是全域内多少个数的约数。
比如 ⌊ n 2 ⌋ \lfloor\frac{n}2\rfloor ⌊2n⌋表示在 [ 1 , n ] [1,n] [1,n]中,有 ⌊ n 2 ⌋ \lfloor\frac{n}{2}\rfloor ⌊2n⌋个数有因子2,它们是: 2 × 1 , 2 × 2 , 2 × 3...2 × ⌊ n 2 ⌋ 2\times 1,2\times 2,2\times 3...2\times \lfloor\frac{n}2\rfloor 2×1,2×2,2×3...2×⌊2n⌋
所以我们现在就有这么一个式子来求值。
整除分块:
考虑有很多 ⌊ n i ⌋ \lfloor\frac{n}i\rfloor ⌊in⌋是相等的,这些我们可以放在一起计算,这就是整除分块的核心思想。
而所有不同的 ⌊ n i ⌋ \lfloor\frac{n}i\rfloor ⌊in⌋最多只有 O ( n ) O(\sqrt n) O(n)种。
考虑当 i ≤ n i\leq \sqrt n i≤n的时候,显然只有不超过 n \sqrt n n种不同的取值,当 i > n i > \sqrt n i>n的时候, ⌊ n i ⌋ ≤ n \lfloor\frac{n}i\rfloor\leq \sqrt n ⌊in⌋≤n也只有不超过 n \sqrt n n种不同的取值,所以不同值的规模不超过 O ( n ) O(\sqrt n) O(n)
所以怎么分块,对于一个值 ⌊ n i ⌋ \lfloor\frac{n}i\rfloor ⌊in⌋,要得到它的 i i i的值需要满足 i ∈ [ ⌊ n ⌊ n i ⌋ + 1 ⌋ + 1 , ⌊ n ⌊ n i ⌋ ⌋ ] i\in [\Big\lfloor\frac{n}{\lfloor\frac{n}{i}\rfloor+1}\Big\rfloor+1,\Big\lfloor\frac{n}{\lfloor\frac{n}i\rfloor}\Big\rfloor] i∈[⌊⌊in⌋+1n⌋+1,⌊⌊in⌋n⌋]
博主自己口胡的,并不清楚有没有什么问题的证明:
考虑证明这个区间的上界是上确界(就是不能再扩展了),下界就显然了(上一个区间的上界+1)。
首先设 n ÷ i = k . . . s n\div i=k...s n÷i=k...s,那么根据带余除法的定义,显然 ⌊ n i ⌋ = k \lfloor\frac{n}{i}\rfloor=k ⌊in⌋=k。
接下来分类讨论:
i ≤ n i\leq \sqrt n i≤n:
首先我们证明这个时候所有的 ⌊ n i ⌋ \lfloor\frac{n}i\rfloor ⌊in⌋值都不相同,即证明 ⌊ n i ⌋ ≠ ⌊ n i + 1 ⌋ \lfloor\frac{n}i\rfloor\not=\lfloor\frac{n}{i+1}\rfloor ⌊in⌋=⌊i+1n⌋。
由于 i ≤ n i\leq \sqrt n i≤n,显然有 k ≥ n ≥ i > s k\geq \sqrt n\geq i > s k≥n≥i>s
考虑反证,假设 ⌊ n i ⌋ = ⌊ n i + 1 ⌋ \lfloor\frac{n}i\rfloor=\lfloor\frac{n}{i+1}\rfloor ⌊in⌋=⌊i+1n⌋
此时设 p = n − k ( i + 1 ) p=n-k(i+1) p=n−k(i+1),显然我们需要 0 ≤ p ≤ i + 1 0\leq p \leq i+1 0≤p≤i+1
利用 n n n建立等式: n = i k + s + ( k − s + p ) = n + ( k − s + p ) n=ik+s+(k-s+p)=n+(k-s+p) n=ik+s+(k−s+p)=n+(k−s+p)
而我们有 k − s > 0 , p ≥ 0 k-s> 0,p\geq 0 k−s>0,p≥0,显然这里就出现了矛盾,假设恒不成立,原命题得证。
那么我们在这一段只需要证明 ⌊ n ⌊ n i ⌋ ⌋ = i \lfloor\frac{n}{\lfloor\frac{n}i\rfloor}\rfloor=i ⌊⌊in⌋n⌋=i就行了。
接下来尝试证明 ⌊ n k ⌋ = i \lfloor\frac{n}k\rfloor=i ⌊kn⌋=i
设 n ÷ k = ( i + t ) . . . w n\div k=(i+t)...w n÷k=(i+t)...w。
再次利用 n n n构建等式: n = k ( i + t ) + w = i k + s n=k(i+t)+w=ik+s n=k(i+t)+w=ik+s k t + w = s kt+w=s kt+w=s
因为 s < i ≤ n s<i\leq \sqrt n s<i≤n, k ≥ n k\geq \sqrt n k≥n,而且 k , t , w , s ≥ 0 k,t,w,s\geq 0 k,t,w,s≥0
所以上式成立当且仅当 t = 0 , w = s t=0,w=s t=0,w=s。
所以 ⌊ n ⌊ n i ⌋ ⌋ = ⌊ n k ⌋ = i \lfloor\frac{n}{\lfloor\frac{n}i\rfloor}\rfloor=\lfloor\frac{n}k\rfloor=i ⌊⌊in⌋n⌋=⌊kn⌋=i,得证。
i > n i>\sqrt n i>n:
显然这时候有 k ≤ n k\leq \sqrt n k≤n,这时候我们要证明的就是 ⌊ n ⌊ n i ⌋ ⌋ = ⌊ n k ⌋ = i m a x \lfloor\frac{n}{\lfloor\frac{n}{i}\rfloor}\rfloor=\lfloor\frac{n}k\rfloor=i_{max} ⌊⌊in⌋n⌋=⌊kn⌋=imax
由于除法运算的单调性, i m a x i_{max} imax显然有如下性质: ⌊ n i m a x ⌋ = ⌊ n i ⌋ = k \lfloor\frac{n}{i_{max}}\rfloor=\lfloor\frac{n}{i}\rfloor=k ⌊imaxn⌋=⌊in⌋=k, ⌊ n i m a x + 1 ⌋ ≠ ⌊ n i ⌋ = k \lfloor\frac{n}{i_{max}+1}\rfloor\not=\lfloor\frac{n}i\rfloor=k ⌊imax+1n⌋=⌊in⌋=k
也就是说我们要证明: ⌊ n ⌊ n k ⌋ ⌋ = k , ⌊ n ⌊ n k ⌋ + 1 ⌋ ≠ k \lfloor\frac{n}{\lfloor\frac{n}{k}\rfloor}\rfloor=k,\lfloor\frac{n}{\lfloor\frac{n}{k}\rfloor+1}\rfloor\not = k ⌊⌊kn⌋n⌋=k,⌊⌊kn⌋+1n⌋=k
好的这个刚才已经证明过了。
为什么? k ≤ n k\leq \sqrt n k≤n,刚才 i ≤ n i\leq \sqrt n i≤n的部分是不是已经证明过了?
综上,原命题得证。
代码:
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define re register
ll mod=998244353;
inline ll solve(ll n){
ll ans=0;
for(ll re i=1,j;i<=n;i=j+1){
j=n/(n/i);
(ans+=(n/i)*(j-i+1)%mod)%=mod;
}
return ans%mod;
}
ll l,r;
signed main(){
cin>>l>>r;
cout<<(solve(r)-solve(l-1)+mod)%mod;
return 0;
}