2020 算法上机赛 C2 - B 减半

题面

Kazamori 有 \(n\) 个正整数。每次操作可以使一个数的值变为原来的一半(除以 2 向下舍入)。现在 Kazamori 想知道,进行 \(k\) 次操作后,这些数的和的最小值是多少。

输入

多组输入数据

每组数据第一行两个正整数 \(n,k\) , 接下来一行用空格隔开的 \(n\) 个正整数 \(a_i\)

输出

每组数据输出一行,一个整数,表示和的最小值。

输入样例

1 1
3

输出样例

1

数据范围

\(1≤n≤10^5,1≤k≤10^5\)

\(1≤ai≤10^9\)

做法

贪心,每次选出最大的数字进行操作

找最大值的过程用一个堆维护,复杂度 \(O(n\log n)\)

#include <bits/stdc++.h>

using namespace std;
typedef long long ll;
inline ll read() {
    ll q=0,w=1;char c=getchar();
    while(!isdigit(c)){if(c=='-')w=-1;c=getchar();}
    while(isdigit(c))q=q*10+c-'0',c=getchar();
    return w*q;
}

ll n, k; long long ans;

void work() {
    priority_queue<ll> Q;
    for(int i = 1;i <= n; ++i) {
        ll x = read(); ans += x;
        Q.push(x);
    }
    while(k--) {
        ll x = Q.top(); Q.pop(); ans -= x;
        x = x / 2; Q.push(x); ans += x;
    }
    cout << ans << endl;
}

int main() {
    while(scanf("%lld%lld", &n, &k) != EOF) {
        ans = 0;
        work();
    }
    return 0;
}
posted @ 2020-12-31 13:55  Withinlover  阅读(80)  评论(0)    收藏  举报