Codeforces Round #701 (Div. 2) C. Floor and Mod

Codeforces Round #701 (Div. 2) C. Floor and Mod
https://codeforces.ml/contest/1485/problem/C


signed main() {
	int t; scanf("%d", &t);
	//第一种思路是按列相加,范围是b = 2 to sqrt(x)
	//这种思路是算出首项,然后后项递推, ans += 递推项
	/*while (t--) {
		int x, y; scanf("%d %d", &x, &y);
		int cnt = min(x - 2, y - 1);
		ll ans = cnt >= 0 ? cnt : 0;
		for (int i = 3; cnt; ++i) {
			ll tmp = 1ll * i * i - 1;
			if (x < tmp)	break;
			cnt = min(1ll * cnt - 1, (x - tmp) / (i - 1) + 1);
			ans += cnt;
		}
		printf("%lld\n", ans);
	}*/
	//这种思路是不由首项递推,每项是尾减头 ans += min(y, x /(b-1) - 1) - b + 1
	/*while (t--) {
		int x, y; scanf("%d %d", &x, &y);
		ll ans = 0;
		for (int i = 2; ; ++i) {
			int r = min(y, x / (i - 1) - 1);
			if (r >= i)	ans += r - i + 1;
			else break;
		}
		printf("%lld\n", ans);
	}*/

	//第二种思路是按行相加,范围是b = 2 to y,ans += min(b-1,x/(b+1))
	//可通过整除分块优化,令b-1=x/(b+1),区间b<=sqrt(x+1)累加,b>sqrt(x+1)做区间加法
	//令l = b + 1, 原式x/b+1变为x/l,其他套整除分块模板即可,注意限制条件b<=min(y,x-1),则l,r<=min(y+1,x)
	while (t--) {
		int x, y; scanf("%d %d", &x, &y);
		int cnt = min((int)sqrt(x + 1), y);
		ll ans = 1ll * cnt * (cnt - 1) / 2;
		for (int l = cnt + 2, r; l <= min(x, y + 1); l = r + 1) {
			r = min(x / (x / l), y + 1);
			ans += 1ll * (x / l) * (r - l + 1);
		}
		printf("%lld\n", ans);
	}
	return 0;
}

posted @ 2021-03-05 21:32  wansheking  阅读(23)  评论(0)    收藏  举报