https://vjudge.net/problem/CodeForces-1251Dhtml
您是一個大型企業的負責人。在您的企業當中共有n位員工爲您工做,並且很是有趣的事是這個n是一個奇數(n不能被2整除)。node
您必須給你的員工分配工資。最初,您有s美圓,而第ii個員工應得的薪水應該是li∼ri之間的一個值。而不管怎麼分配每一個人的工資,您必須使得全部分配的工資的中位數最大。ios
對於一個長度爲奇數的序列,若是要找到他的中位數,就須要先對這個序列進行排序,以後找到中間位置的數字。舉例來講:c++
保證您有足夠的錢來支付最低的工資,即l1+l2+⋯+ln≤s。spa
注意,您沒必要把全部的錢都花在員工的開支上。.net
假設符合要求的中位數爲x,首先,按右端點從小到大排序,ri的中位數便是x的上界;按左端點排序,獲得x的下界爲li的中位數。這個很好理解,畫個數軸,基本就是那回事。。而後咱們在x的上下界裏二分,check所花費用是否小於等於s便可。怎麼check呢?考慮貪心,對於ri<x的數,咱們就取li,這樣能夠騰出更多的資金;對於li>x的數,咱們取li,也是爲了騰出更多資金;對於li~ri穿插x的數,咱們先丟一塊兒。經過剛纔的判斷咱們能夠獲得放到x左邊和右邊的個數,如今咱們遍歷穿插的數,若是當前x左邊的個數小於右邊,那麼這個數得用來放到左邊,用最小的li便可;不然放到右邊,用x的值便可。最後還剩一個數,那就是中位數x啦,因此判斷tmp+x<=s便可。htm
#include<bits/stdc++.h> using namespace std; #define inf 0x3f3f3f3f #define ll long long const int N=200005; const int mod=1e9+7; const double eps=1e-8; const double PI = acos(-1.0); #define lowbit(x) (x&(-x)) struct node { ll l,r; } g[N]; int n; ll s; bool cmp1(node a,node b) { return a.l<b.l; } bool cmp2(node a,node b) { return a.r<b.r; } node gg[N]; bool check(ll x) { ll tmp=0,l=0,r=0,cnt=0; for(int i=1; i<=n; i++) { if(g[i].l>x) tmp+=g[i].l,r++; else if(g[i].r<x) { tmp+=g[i].l,l++; } else { gg[cnt++]=g[i]; } } int i=0,j=cnt-1; while(i<j) { if(l<r) tmp+=gg[i].l,l++,i++; else tmp+=x,r++,j--; } // cout<<"gg"<<endl; return tmp+x<=s; } int main() { std::ios::sync_with_stdio(false); int t; cin>>t; while(t--) { cin>>n>>s; for(int i=1; i<=n; i++) { cin>>g[i].l>>g[i].r; } sort(g+1,g+1+n,cmp2); ll R=g[n/2+1].r; sort(g+1,g+1+n,cmp1); ll L=g[n/2+1].l; ll l=L,r=R,mid,ans=L; while(l<=r) { mid=(l+r)>>1; if(check(mid)) { l=mid+1; ans=mid; } else r=mid-1; } cout<<ans<<endl; } return 0; }