CodeForces Bubble Cup 11 - Finals [Online Mirror, Div. 2] F题

Splitting money

time limit per test

1 second

memory limit per test

256 megabytes

input

standard input

output

standard output

After finding and moving to the new planet that supports human life, discussions started on which currency should be used. After long negotiations, Bitcoin was ultimately chosen as the universal currency.

These were the great news for Alice, whose grandfather got into Bitcoin mining in 2013, and accumulated a lot of them throughout the years. Unfortunately, when paying something in bitcoin everyone can see how many bitcoins you have in your public address wallet.

This worried Alice, so she decided to split her bitcoins among multiple different addresses, so that every address has at most xx satoshi (1 bitcoin = 108108 satoshi). She can create new public address wallets for free and is willing to pay ff fee in satoshi per transaction to ensure acceptable speed of transfer. The fee is deducted from the address the transaction was sent from. Tell Alice how much total fee in satoshi she will need to pay to achieve her goal.

Input

First line contains number NN (1≤N≤2000001≤N≤200000) representing total number of public addresses Alice has.

Next line contains NN integer numbers aiai (1≤ai≤1091≤ai≤109) separated by a single space, representing how many satoshi Alice has in her public addresses.

Last line contains two numbers xx, ff (1≤f<x≤1091≤f<x≤109) representing maximum number of satoshies Alice can have in one address, as well as fee in satoshies she is willing to pay per transaction.

Output

Output one integer number representing total fee in satoshi Alice will need to pay to achieve her goal.

Example

Input

Copy

3
13 7 6
6 2

Output

Copy

4

Note

Alice can make two transactions in a following way:

0. 13 7 6 (initial state)

1. 6 7 6 5 (create new address and transfer from first public address 5 satoshies)

2. 6 4 6 5 1 (create new address and transfer from second address 1 satoshi)

Since cost per transaction is 2 satoshies, total fee is 4.

思路:

先说一下题意,大致就是给你一些整数序列a,并给出一个限制x,和花费f,对于序列中的每个数ai,要把ai分成不大于x的一些数,每分一次需要花费f,求最小花费

很明显,每次等分是最小的花费策略,但是要保证分到最后是x才花费最少,于是贪心,对一一个数ai,我们先分出最大的

2^p * x(即分成了p份),需要花费(2^p - 1 + 1)* f(1 + 2 + 4 + ........ + 2……2^(p - 1) = 2^p - 1,最后又+1是因为第一次分成2^p * x和ai - 2^p * x也需要一次花费) = 2^p * f,剩下的仍然这样分,这样就剩下一个问题,如果最后剩下的恰好要分却只能分得1,如样例中的7,这样肯定是不符合上述规律的,这样我们只需要特判一下 x + 1 <= ai <= x + f的情况即可

代码:

#include<bits/stdc++.h>
using namespace std;
#define ll long long
const ll maxn = (ll)2e5 +10;
ll a[maxn],p[35],pos = 0;
void init()
{
    ll w = 1;
    for (int i = 0;i < 31;i ++)
    {
        p[pos ++] = w;
        w *= 2;
    }
    pos --;
}
int main()
{
    init();
    ll n,f,x;
    scanf("%lld",&n);
    for (int i = 0;i < n;i ++)
        scanf("%lld",&a[i]);
    scanf("%lld %lld",&x,&f);
    ll ans = 0;
    for (int i = 0;i < n;i ++)
    {
        if (a[i] > x)
            for (int j = pos;j >= 0;j --)
            {
                ll t = p[j] * (x + f);
                if (t + 1 <= a[i])
                {
                    ans += p[j] * f;
                    a[i] -= t;
                }
            }
        if (a[i] > x && a[i] <= x + f)
            ans += f;
    }
    printf("%lld\n",ans);
    return 0;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值