題:https://codeforces.com/contest/1251/problem/D
題意:給你n個單位需要滿足達到的區間,再給個s,s是要分配給n的單位的量,當然∑l<=s,問經過分配后能夠達到的最大中位數是多少
題解:二分找中位數,成立原因:代碼注釋

#include<bits/stdc++.h> using namespace std; typedef long long ll; #define fo(i,a,b) for(int i=a;i<=b;i++) #define fod(i,a,b) for(int i=b;i>=a;i--) #define pb push_back #define pll pair<ll,ll> const int inf=0x3f3f3f3f; const ll INF=1e18; vector<pll>a; int n; ll s; ll check(ll m){///挑出能達到中位數midd的都要達到中位數和已經比中位數大的數,且只能取一半+1個 ///因為a 已經按照從大到小排序了,所以從前往后地挑出能達到midd的來加肯定是耗錢最少的 int countt=a.size()/2+1; ll sum=0; for(int i=0;i<a.size();i++){ if(a[i].first<=m&&a[i].second>=m&&countt){ sum+=m; countt--; } else{ sum+=a[i].first; if(a[i].first>m) countt--; } } if(countt) return s+10;//讓這一步不合法 else return sum; } int main(){ int t; cin>>t; while(t--){ scanf("%d%I64d",&n,&s); a.clear(); fo(i,1,n){ ll x,y; scanf("%I64d%I64d",&x,&y); a.pb(make_pair(x,y)); } sort(a.begin(),a.end()); reverse(a.begin(),a.end()); ll l=a[a.size()/2].first+1,r=s; while(l<=r){ ll midd=(l+r)>>1; if(check(midd)<=s) l=midd+1; else r=midd-1; } printf("%I64d\n",l-1); } return 0; }