码迷,mamicode.com
首页 > 其他好文 > 详细

CF1251D Salary Changing

时间:2020-03-04 23:01:17      阅读:73      评论:0      收藏:0      [点我收藏+]

标签:端点   node   line   def   sum   没有   lse   problem   can   

CF1251D Salary Changing

按照左端点从小到大排序,然后二分答案x贪心判断。

倒着扫

最优情况是(n/2+1)个x,其余数取左端点。

首先,如果这个节点的右端点比x大并且还没取满n/2+1个,优先把这个人的工资设成x,因为它的左端点一定没有l更小的优。

否则直接取左端点。

#include<bits/stdc++.h>
using namespace std;
#define int long long
const int N=200005;
const int inf=1e15;
int T,n,s,l,r,ans;
inline int max(const int &a,const int &b) {
    return a>b?a:b;
}
inline int min(const int &a,const int &b) {
    return a<b?a:b;
}
struct node {
    int l,r;
}a[N];
bool cmp(const node &a,const node &b) {
    return a.l<b.l;
}
bool check(int x) {
    int sum=n/2+1,total=s;
    for(int i=n;i>=1;--i) {
        if(a[i].r>=x&&sum) {
            total-=max(x,a[i].l);
            --sum;
        } else {
            total-=a[i].l;
        }
    }
    return (!sum)&&(total>=0);
}
signed main() {
    scanf("%lld",&T);
    while(T--) {
        l=inf,r=0;
        scanf("%lld%lld",&n,&s);
        for(int i=1;i<=n;++i)
            scanf("%lld%lld",&a[i].l,&a[i].r),l=min(l,a[i].l),r=max(r,a[i].r);
        sort(a+1,a+n+1,cmp);
        while(l<=r) {
            int mid=(l+r)>>1;
            if(check(mid))ans=mid,l=mid+1;
            else r=mid-1;
        }
        printf("%lld\n",ans);
    }
    return 0;
}

CF1251D Salary Changing

标签:端点   node   line   def   sum   没有   lse   problem   can   

原文地址:https://www.cnblogs.com/zzctommy/p/12416457.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!