BZOJ 1257 余数之和 题解
这道题是一道整除分块的模板题;
首先,知道分块的人应该知道,n/i最多有2*sqrt(n)种数,但这和余数有什么关系呢?
注意,只要n/i的值和n/(i+d)的值一样,那么n%i到n%(i+d)的值就是一个等差数列!因为n/i=n/(i+1)*(i+1)=n/i*(i+1)=n/i*i+n/i;
所以在向下取整的情况下它是公差为n/i的等差数列;
因此运用分块的性质和等差数列求和公式就可以切掉这道题;
#include <bits/stdc++.h> using namespace std; long long n,k; int main() { cin>>n>>k; long long ans=n*k; for(register long long l=1,r;l<=n;l=r+1){ if(k/l==0) r=n; else r=min(k/(k/l),n); ans-=((r-l+1)*(k/l*l)+(r-l+1)*(r-l)/2*(k/l)); } cout<<ans; }
众人皆醉我独醒,举世皆浊我独清