P2261 [CQOI2007]余数求和

题目

题目给定柿子\(\displaystyle G(n,k)=\sum_{i=1}^{n}k\ mod\ i\)

我们知道\(mod\)是取模运算,即\(n\)整取\(k\)后的余数

∴我们设可以知道\(k\ mod\ i =k-i*\lfloor{\frac {k}{i}}\rfloor\)

∴我们的柿子就阔以变成这个亚子\(\displaystyle G(n,k)=\sum_{i=1}^{n}{k-i*\lfloor{\frac{k}{i}}\rfloor}\)

我们可以在把柿子简化一下

使这个柿子变成了\(\displaystyle n*k-\sum_{i=1}^{n}{i*\lfloor{\frac{k}{i}}\rfloor}\)

我们就不难发现我们只需要考虑降低一下后面这个\(\sum\)的复杂度了

我们考虑一个数\(k\)

我们发现当\(i>k\)的时候,那么\(\lfloor{\frac{k}{i}}\rfloor\)一定是等于\(0\)
(因为分母比分子大了),所以我们在程序中判断一下\(k\)\(i\)的大小关系就阔以了

然后我们考虑一下当\(i\leq k\)的时候呢,这个时候我们就要考虑一下\(\lfloor \frac{k}{i}\rfloor\)的数值的关系了

我们考虑一个数\(i\),且存在\(j=\lfloor \frac{k}{\lfloor \frac{k}{i}\rfloor}\rfloor\),我们就会发现\(\lfloor\frac{k}{j}\rfloor\)=\(\lfloor \frac{k}{i}\rfloor\),是不是很神奇?(读者可自行举栗子来验证一下)

我们会惊奇地发现:当\(i\)\(i\)\(\lfloor\frac{k}{\lfloor \frac{k}{i}\rfloor}\rfloor\)(即\(j\))的区间里所有\(\lfloor \frac{k}{i} \rfloor\)都会是同一个值

这其实是数论分块的一部分,这其实是个除法分块

然后放代码(较丑勿喷)

#include<bits/stdc++.h>
using namespace std;
long long ans, n, k;
int main(){
	scanf("%lld%lld", &n, &k);
	ans = n * k;
	for(int i = 1, j = 1; i <= n; i = j + 1){
		if(i <= k) j = min(n, k/ (k / i));//防止j越界 
		else break;//i > k时(k/i == 0) 直接退出
		ans -= (k / i) * (j - i + 1) * (i + j) / 2;
	}
	printf("%lld\n", ans);
	return 0;
}

完美结束,撒花✿✿ヽ(°▽°)ノ✿

posted @ 2020-07-20 15:42  Tethys  阅读(156)  评论(3编辑  收藏  举报