Codeforces Round #339 D. Skills

                                                             D. Skills
                                                   time limit per test
                                                          2 seconds
                                               memory limit per test
                                                    256 megabytes
 

Lesha plays the recently published new version of the legendary game hacknet. In this version character skill mechanism was introduced. Now, each player character has exactlyn skills. Each skill is represented by a non-negative integerai — the current skill level. All skills have the same maximum levelA.

Along with the skills, global ranking of all players was added. Players are ranked according to the so-called Force. TheForce of a player is the sum of the following values:

  • The number of skills that a character has perfected (i.e., such that ai = A), multiplied by coefficientcf.
  • The minimum skill level among all skills (min ai), multiplied by coefficientcm.

Now Lesha has m hacknetian currency units, which he is willing to spend. Each currency unit can increase the current level of any skill by1 (if it's not equal toA yet). Help him spend his money in order to achieve the maximum possible value of the Force.

Input

The first line of the input contains five space-separated integers n, A, cf, cm and m (1 ≤ n ≤ 100 000, 1 ≤ A ≤ 109, 0 ≤ cf, cm ≤ 1000,0 ≤ m ≤ 1015).

The second line contains exactly n integersai (0 ≤ ai ≤ A), separated by spaces, — the current levels of skills.

Output

On the first line print the maximum value of the Force that the character can achieve using no more thanm currency units.

On the second line print n integers a'i (ai ≤ a'i ≤ A), skill levels which one must achieve in order to reach the specified value of the Force, while using no more than m currency units. Numbers should be separated by spaces.


Examples

Input
3 5 10 1 5
1 3 1
Output
12
2 5 2 

Input
3 5 10 1 339
1 3 1
Output
35
5 5 5 

Note

In the first test the optimal strategy is to increase the second skill to its maximum, and increase the two others by1.

In the second test one should increase all skills to maximum.






//總體思路:  暴力加二分,

//枚舉[i+1,n]技能都被升到頂級了, [0,i]維護一個儘可能大的最低技能等級

#include<bits/stdc++.h>
using namespace std;

typedef long long llint;
const int maxn = 1e5 + 100;
struct Node {
    llint val;
    int pos;
} a[maxn];
llint dp[maxn];
llint A, fmaxx, fminn, m;
int n;

int cmp1(Node aa, Node bb) {
    return aa.val < bb.val;
}

int cmp2(Node aa, Node bb) {
    return aa.pos < bb.pos;
}

llint solve(llint mm, int start) { //二分搜索剩下的mm值可以填充的最大的最小值
      if(start == 0)
        return A;  //這裏非常重要, 想想爲什麼,  測試數據 6 就是這個  1 100 1 2 30  71;
      int l = 0, r = start - 1;
      int mid;
      while(l < r){
        mid = (l + r + 1) / 2;   //由於是取左邊界, 故。。。
        llint need =(llint) dp[mid] - (A - a[mid].val) * (mid + 1); // 填充到mid ,所需要的話費
        if(need < mm){
            l = mid;
        }else{
            r = mid - 1;
        }
      }
      llint need =(llint) dp[l] - (A - a[l].val) * (l + 1); //需要的花費
      llint ans =(llint) a[l].val + (mm - need) / (l + 1);
      return min(A, ans);;

}

int  main() {
    //freopen("in.txt", "r", stdin);
    scanf("%d %I64d %I64d %I64d %I64d", &n, &A, &fmaxx, &fminn, &m);

    //由於輸出需要原始序列, 故用結構體保存;
    for(int i = 0; i < n; i++) {
        scanf("%I64d", &a[i].val);
        a[i].pos = i;
    }
    //按照輸入的值的大小排序;
    sort(a, a + n, cmp1);

    //dp[I] 表示使0 - i 都保存到A需要多少錢;
    for(int i = 0; i < n; i++) {
        if(i == 0) {
            dp[i] = A - a[i].val;
        } else {
            dp[i] = dp[i-1] + A - a[i].val;
        }
    }

    llint ans_number = -1;   //升級之後最大的最小值;
    llint ans_pos = -1;      //升級之後第一個填充滿的位置
    llint ans = -1;          //最後的值
    llint mm = m;
    a[n].val = A;            //這裏是爲了,當一個都不填充滿的時候。
    for(int i = n - 1; i>=-1; i--){
        mm -= (A - a[i+1].val);   //剩下的 mm 值
        if(mm < 0)                //如果小與 0 就退出,  等於0的時候還需要查找最小的值, 故不退出!
            break;
        llint tem_x = solve(mm, i+1); //填充後序列中最小值
        llint tem_p = tem_x * fminn + (n - i - 1) * fmaxx;  //兩個部分相加
        if(tem_p > ans){                  // 如果大於, 就更新值
            ans = tem_p;
            ans_number = tem_x;
            ans_pos = i + 1;
        }
    }
    // 小與平均值的都更新爲平均值
    for(int i = 0; i < n; i++){
       a[i].val = max(a[i].val, ans_number);
    }
    //填充滿的更新爲A的值
    for(int i = ans_pos; i <n; i++){
        a[i].val = A;
    }
    //按照原始下標排序
    sort(a, a+n, cmp2);

    //輸出
    printf("%I64d\n", ans);
    for(int i = 0; i < n; i++)
    {
        i == n-1 ? printf("%I64d\n", a[i].val) : printf("%I64d ", a[i].val);
    }

}







發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章