首页 > 其他 > 详细

CF613B Skills

时间:2020-03-04 23:27:26      阅读:71      评论:0      收藏:0      [点我收藏+]

CF613B Skills

挺毒瘤的哈。

从大到小排序能力值,然后枚举能把几个技能升满级。对于剩下的二分答案,找到能达到的最大的最小能力值。

#include<bits/stdc++.h>
using namespace std;
#define int long long
const int N=100005;
int n,A,cf,cm,m,sum[N],ans=-1,rk,v,b[N];
struct node{
    int val,id;
}a[N];
bool cmp(const node &a,const node &b) {
    return a.val<b.val;
}
int find(int sum,int x) {
    int l=0,r=x,res;
    while(l<=r) {
        int mid=(l+r)>>1;
        if(a[mid].val<sum)res=mid,l=mid+1;
        else r=mid-1;
    } 
    return res;
}
signed main() {
    scanf("%lld%lld%lld%lld%lld",&n,&A,&cf,&cm,&m);
    for(int i=1;i<=n;++i)
        scanf("%lld",&a[i].val),a[i].id=i;
    sort(a+1,a+n+1,cmp);
    for(int i=1;i<=n;++i)
        sum[i]=sum[i-1]+a[i].val;
    m+=sum[n];
    for(int i=1;i<=n+1;++i) {
        if(A*(n-i+1)+sum[i-1]>m)continue;
        int l=a[1].val,r=A,res;
        while(l<=r) {
            int mid=(l+r)>>1;
            int t=find(mid,i-1);
            if(A*(n-i+1)+mid*t+sum[i-1]-sum[t]<=m)res=mid,l=mid+1;
            else r=mid-1;
        }
        if(ans<res*cm+(n-i+1)*cf) {
            ans=res*cm+(n-i+1)*cf;
            rk=i,v=res;
        }
    }
    printf("%lld\n",ans);
    for(int i=1;i<rk;++i)a[i].val=max(a[i].val,v);
    for(int i=rk;i<=n;++i)a[i].val=A;
    for(int i=1;i<=n;++i)b[a[i].id]=a[i].val;
    for(int i=1;i<=n;++i)printf("%lld ",b[i]);
    return 0;
 } 

CF613B Skills

原文:https://www.cnblogs.com/zzctommy/p/12416505.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!