题意:
给出n,kn,kn,k,求出
∑i=1nk mod i
\sum_{i=1}^{n}k\ mod\ i
i=1∑nk mod i
Solution:
由于k mod i=k−⌊ki⌋⋅ik\ mod\ i=k-\lfloor\frac{k}{i}\rfloor\cdot ik mod i=k−⌊ik⌋⋅i,于是只需要求
nk−∑i=1n⌊ki⌋⋅i
nk-\sum_{i=1}^{n}\lfloor\frac{k}{i}\rfloor\cdot i
nk−i=1∑n⌊ik⌋⋅i
对于一段使⌊ki⌋\lfloor\frac{k}{i}\rfloor⌊ik⌋相同的iii,可以利用等差数列求和这一段
现在考虑对于一个lll,如何找到最大的rrr满足
⌊kl⌋=⌊kr⌋ \lfloor\frac{k}{l}\rfloor=\lfloor\frac{k}{r}\rfloor ⌊lk⌋=⌊rk⌋
有这样的等式满足
⌊kl⌋=⌊kr⌋≤kr \lfloor\frac{k}{l}\rfloor=\lfloor\frac{k}{r}\rfloor\leq\frac{k}{r} ⌊lk⌋=⌊rk⌋≤rk
于是
r≤k⌊kr⌋=k⌊kl⌋⇒rmax=⌊k⌊kl⌋⌋ 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]使⌊kl⌋=⌊kr⌋\lfloor\frac{k}{l}\rfloor=\lfloor\frac{k}{r}\rfloor⌊lk⌋=⌊rk⌋,只需要对r+1r+1r+1作为新的左端点时重新计算即可,并且当⌊kl⌋=0\lfloor\frac{k}{l}\rfloor=0⌊lk⌋=0时,r=+∞r=+\inftyr=+∞。无论何种情况,切莫忘记题目≤n\leq n≤n的限制
时间复杂度
设i⋅j=ki\cdot j=ki⋅j=k
当i≤ni\leq \sqrt{n}i≤n时,j≥nj\geq \sqrt{n}j≥n,此时iii最多n\sqrt{n}n种取值,对应的jjj只可能有一个取值,于是此时最多有n\sqrt{n}n种⌊ki⌋\lfloor\frac{k}{i}\rfloor⌊ik⌋
同理对i≥ni\geq \sqrt{n}i≥n,此时相当于i,ji,ji,j轮换,取值种数仍然是n\sqrt{n}n种
于是总取值不超过2n2\sqrt{n}2n种,时间复杂度O(n)O(\sqrt{n})O(n)
// #include<bits/stdc++.h>
#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<vector>
#include<bitset>
#include<map>
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;
}
691

被折叠的 条评论
为什么被折叠?



