对于任意的\(b\in [l, r]\), 那么\(a \% b\)的范围一定是\([0, b-1]\), 即\(a\%b\)的最大值为\(b - 1\),此时a最小能取的值为\(b + b - 1\), 暴力的思路就是从l到r枚举b,取最后一个能够满足\(b+ b-1 \le r\)的b,此时令a = 2b-1,取得最大值
设l足够小,当r为奇数的时候,一定存在一个\(b_i\),使得\(b_i + b_i - 1\)正好等于r,那么所有比\(b_i\)大的\(b_k\)均有\(b_k + b_k-1>r\),当b取\(b_k\)的时候,a取r达到a % b的最大值为\(r-b_k\),由于\(b_i + b_i - 1=r\),并且\(b_k \ge b_i + 1\), 所以\(r-b_k \le r - b_i - 1 = b_i-2\),所以此时取b = (r + 1) / 2, a = 2b - 1可以取到最大
当r为偶数的时候,一定存在\(b_i\),使得\(b_i + b_i -1 = r - 1\),所有比\(b_i\)大的\(b_k\)均有\(b_k + b_k-1>r\),当b取\(b_k\)的时候,a取r达到a % b的最大值为\(r-b_k\),有\(r - b_k \le r - b_i - 1 = b_i - 1\), 所以当r为偶数时,令b = r / 2, a = 2b - 1可以取到最大
当出现\(l > (r + 1)/2\)时,取b为l,令a = r就行了
#include<iostream>
using namespace std;
int l, r, t;
void solve(){
cin >> l >> r;
int b = max(r + 1 >> 1, l);
int a = min(2 * b - 1, r);
cout << a % b << endl;
}
int main(){
cin >> t;
while(t --) solve();
return 0;
}