CF1562A

对于任意的\(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;
}
posted @ 2021-10-11 20:48  yys_c  阅读(26)  评论(0编辑  收藏  举报