codeforces613B - Skills &&金中市队儿童节常数赛

题目传送门

本随笔写的是第二题......

这道题方法就是搞乱....
因为n较mxa小 所以枚举达到最大上限的点 然后就乱搞 代码看看咯

#include<cstdio>
#include<cstring>
#include<algorithm>
#define LL long long
using namespace std;
const int M=100005;
LL read(){
    LL ans=0; int f=1,c=getchar();
    while(c<'0'||c>'9'){if(c=='-') f=-1; c=getchar();}
    while(c>='0'&&c<='9'){ans=ans*10+(c-'0'); c=getchar();}
    return ans*f;
}
int n,pos;
LL v1,v2,mxa,m,sum[M],end[M],ans=-1;
struct node{int id; LL v;}e[M];
bool cmp(node a,node b){return a.v<b.v;}
int main()
{
    scanf("%d",&n); mxa=read(); v1=read(); v2=read(); m=read();
    for(int i=1;i<=n;i++) e[i].v=read(),e[i].id=i;
    sort(e+1,e+1+n,cmp);
    for(pos=n;pos;pos--){
        sum[pos]=sum[pos+1]+(mxa-e[pos].v);
        if(sum[pos]>m) break;
    }
    pos++;
    LL now,last,use=0,rem,val;
    int putmn=0,putmx=0,id=0;
    for(int i=pos;i<=n+1;i++){
        rem=m-use-sum[i];
        while(id<i-1&&(val=(e[id+1].v-e[id].v)*id)<=rem) id++,rem-=val,use+=val;
        now=e[id].v;
        if(id){
            now+=rem/id;
            now=min(now,mxa); 
        }
        else now=mxa;
        val=v2*now+v1*(n-i+1);
        if(val>ans){
            ans=val; last=now;
            putmn=id; putmx=i;
        }
    }
    printf("%lld\n",ans);
    for(int i=1;i<=putmn;i++) end[e[i].id]=last;
    for(int i=putmn+1;i<putmx;i++) end[e[i].id]=e[i].v;
    for(int i=putmx;i<=n;i++) end[e[i].id]=mxa;
    for(int i=1;i<=n;i++) printf("%lld ",end[i]);
    return 0;
}
View Code

 

posted @ 2017-06-06 10:19  友人Aqwq  阅读(149)  评论(0编辑  收藏  举报