二分+贪心——cf1251D

二分的时候要特别注意一下下界L

#include<bits/stdc++.h>
using namespace std;
#define ll long long 
#define N 200005
 
ll n,s;
struct Node{
    ll l,r;
}p[N];
int cmp(Node a,Node b){
    return a.l<b.l;
}
 
int judge(ll mid){
    int cnt1=0,cnt2=0;
    for(int i=1;i<=n;i++){
        if(p[i].l>mid)cnt2++;
        if(p[i].r<mid)cnt1++;
    }
    if(cnt1>n/2)return 0;//偏大了 
    
    if(1.0*mid*(n/2+1)>s) return 0; 
 
    ll tot=0,cnt=cnt1;
    for(int i=1;i<=n;i++){
        if(p[i].l<=mid && p[i].r>=mid){
            ++cnt;
            if(cnt<=n/2)
                tot+=p[i].l;
            else if(cnt>=n/2+1)
                tot+=mid;
        }
        else tot+=p[i].l;
    } 
    
    if(tot>s)return 0;
    return 1;
}
 
int main(){
    int t;cin>>t;
    while(t--){
        cin>>n>>s;
        for(int i=1;i<=n;i++)
            scanf("%lld%lld",&p[i].l,&p[i].r);
        sort(p+1,p+1+n,cmp);
        
        ll L=p[n/2+1].l,R=s,mid,ans;
        while(L<=R){
            mid=L+R>>1;
            if(judge(mid)){
                ans=mid;
                L=mid+1;
            }
            else {
                R=mid-1;
            }
        }
        
        cout<<ans<<'
';
    }
}
原文地址:https://www.cnblogs.com/zsben991126/p/11737717.html