原题传送门
题目大意:给出正整数n,k,请计算G(n,k)=∑i=1n k mod i
思路:一道整除分块的入门题
整除分块的基本形式为:∑i=1n⌊in⌋
对于任意一个i(i≤n),我们要找到一个最大的j(i≤j≤n),使得⌊in⌋=⌊jn⌋,那么此时j=⌊⌊in⌋n⌋
显然i≤j≤n(证明从略),设k=⌊in⌋,当⌊jn⌋=k,jmax=⌊kn⌋(证明从略)
那么对于每次以[i,j]为一块,分块求和即可
Code:
for(ll l=1,r;l<=n;l=r+1){
r=n/(n/l);
ans+=(r-l+1)*(n/l);
}
对于本题来说,∑i=1n k mod i=∑i=1n k−i∗⌊ik⌋=n∗k−∑i=1n i∗⌊ik⌋
对于∑i=1n i∗⌊ik⌋,我们把每块[l,r]对应的∑i=lr i∗⌊ik⌋中,令T=∑i=lr⌊ik⌋,∑i=lr i∗⌊ik⌋=T∗∑i=lr i=T∗2l+r
复杂度O(n)
Code:
#include <bits/stdc++.h>
using namespace std;
const int N=2e3+10,mod=1e9+7;
typedef long long ll;
ll n,k;
int main(){
cin>>n>>k;
ll ans=n*k;
for(ll l=1,r;l<=n;l=r+1){
if(k/l!=0) r=min(n,k/(k/l));
else r=n;
ans-=(l+r)*(k/l)*(r-l+1)/2;
}
cout<<ans<<endl;
return 0;
}