题意:一共有S元,给n个人分,每个人允许分到的钱数有一个范围( l ~ r ),可以不用完s,问最大的中位数是多少
思路:当时做到这里的时候宿舍也熄灯了,脑子还巨困。。。
比赛的时候想的是把全部人按照( l , r )排序,然后二分中间那个人的可分配范围,看最多能给这个人分配多少钱。
但是这么写有个问题,,,可能不用中间那个人作为中位数,如:
2 4
2 7
4 4
5 6
6 8
这种情况下,如果按照我的思路是4,但是显然可以有,2,7,4,6,8。。。类似这种取法,原因在于 l 小的人可能 r 大,那么他可以取到更大的范围,这么排列就没啥用了!
昨天晚上一直在绞尽脑汁想到底按啥排序,但是其实有问题的是二分。。
二分的时候直接二分1--1e9,每次找出可以比这个值大的数有多少,大于n/2则可能成为中位数,然后贪心分配钱数就好了。

总结:。。还是想的太少
vector<pair<ll, ll> > v, v1;
void solve()
{
    ll n, s,l, r, best;
    ll low, high, mid, val, temp, flag;
    rd(n),rd(s);v.clear();
    val = n / 2 + 1;
    for (int i = 0; i < n; i++)
    {
        rd(l),rd(r);
        v.push_back({l, r});
    }
    sort(v.begin(), v.end());
    low = 0;//
    high = 1e9;//
    while (low <= high)
    {
        flag = 1;
        mid = (low + high) / 2;
        v1.clear();
        temp = 0;
        for (int i = 0; i < v.size(); i++)
        {
            if (v[i].second >= mid)
                v1.push_back(v[i]);
            else
                temp += v[i].first;
        }
        if (v1.size() < val) flag = 0;
        else
        {
            ll idx = v1.size() - val;
            for (int i = 0; i < v1.size(); i++)
            {
                if (i < idx)
                    temp += v1[i].first;
                else
                    temp += max(mid, v1[i].first);
            }
            if (temp > s)
                flag = 0;
        }
        if (flag)
            best = mid,low = mid + 1;
        else
            high = mid - 1;
    }
    printf("%lld\n",best);
}
int main()
{
    int t;rd(t);
    while (t--)
        solve();
    return 0;
}