P2261 [CQOI2007]余数求和(除法分块)

题目链接

题意:求∑k mod i

思路:可以化解为

 

所以,如何求k/i向下取整才是关键,对于一个块k/i=j,我们可以直接求i到j区间的值,i到j区间都为k/i,时间复杂度为sqrt(n)。大体如下证明方法可行性和复杂度

 

 

#include <bits/stdc++.h>
using namespace std;
#define ll long long
const int N=1000005;
int mod=1000;
int a[N];
int c[N];
int main()
{
    ll n,k;
    scanf("%lld%lld",&n,&k);
    ll ans=n*k;
    for(ll l=1,r;l<=n;l=r+1) 
    {
          if(k/l!=0)
            r=min(k/(k/l),n);
          else
            r=n;
          ans-=(k/l)*(r-l+1)*(l+r)/2;
    }
    printf("%lld\n",ans);
}

 

posted @ 2020-10-04 19:29  Ldler  Views(109)  Comments(0Edit  收藏  举报