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;
}