给出
n
,
k
n,k
n,k,求出
∑
i
=
1
n
k
m
o
d
i
\sum_{i=1}^{n}k\ mod\ i
i=1∑nk mod i
由于
k
m
o
d
i
=
k
−
⌊
k
i
⌋
⋅
i
k\ mod\ i=k-\lfloor\frac{k}{i}\rfloor\cdot i
k mod i=k−⌊ik⌋⋅i,于是只需要求
n
k
−
∑
i
=
1
n
⌊
k
i
⌋
⋅
i
nk-\sum_{i=1}^{n}\lfloor\frac{k}{i}\rfloor\cdot i
nk−i=1∑n⌊ik⌋⋅i
对于一段使
⌊
k
i
⌋
\lfloor\frac{k}{i}\rfloor
⌊ik⌋相同的
i
i
i,可以利用等差数列求和这一段
现在考虑对于一个 l l l,如何找到最大的 r r r满足
⌊ k l ⌋ = ⌊ k r ⌋ \lfloor\frac{k}{l}\rfloor=\lfloor\frac{k}{r}\rfloor ⌊lk⌋=⌊rk⌋
有这样的等式满足
⌊ k l ⌋ = ⌊ k r ⌋ ≤ k r \lfloor\frac{k}{l}\rfloor=\lfloor\frac{k}{r}\rfloor\leq\frac{k}{r} ⌊lk⌋=⌊rk⌋≤rk
于是
r ≤ k ⌊ k r ⌋ = k ⌊ k l ⌋ ⇒ r m a x = ⌊ k ⌊ k l ⌋ ⌋ r\leq\frac{k}{\lfloor\frac{k}{r}\rfloor}=\frac{k}{\lfloor\frac{k}{l}\rfloor}\Rightarrow r_{max}=\lfloor\frac{k}{\lfloor\frac{k}{l}\rfloor}\rfloor r≤⌊rk⌋k=⌊lk⌋k⇒rmax=⌊⌊lk⌋k⌋
此时找出了最大的 [ l , r ] [l,r] [l,r]使 ⌊ k l ⌋ = ⌊ k r ⌋ \lfloor\frac{k}{l}\rfloor=\lfloor\frac{k}{r}\rfloor ⌊lk⌋=⌊rk⌋,只需要对 r + 1 r+1 r+1作为新的左端点时重新计算即可,并且当 ⌊ k l ⌋ = 0 \lfloor\frac{k}{l}\rfloor=0 ⌊lk⌋=0时, r = + ∞ r=+\infty r=+∞。无论何种情况,切莫忘记题目 ≤ n \leq n ≤n的限制
设 i ⋅ j = k i\cdot j=k i⋅j=k
当 i ≤ n i\leq \sqrt{n} i≤n时, j ≥ n j\geq \sqrt{n} j≥n,此时 i i i最多 n \sqrt{n} n种取值,对应的 j j j只可能有一个取值,于是此时最多有 n \sqrt{n} n种 ⌊ k i ⌋ \lfloor\frac{k}{i}\rfloor ⌊ik⌋
同理对 i ≥ n i\geq \sqrt{n} i≥n,此时相当于 i , j i,j i,j轮换,取值种数仍然是 n \sqrt{n} n种
于是总取值不超过 2 n 2\sqrt{n} 2n种,时间复杂度 O ( n ) O(\sqrt{n}) O(n)
// #include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
using ll=long long;
const int N=1e5+5,inf=0x3fffffff;
const long long INF=0x3fffffffffffffff,mod=1e9+7;
ll n,k;
int main()
{
cin>>n>>k;
ll l=1,ans=1ll*n*k;
while(l<=n)
{
ll val=k/l,r=val?min(n,k/val):n;
ans-=1ll*(l+r)*(r-l+1)/2*val;
l=r+1;
}
cout<<ans;
return 0;
}