题目描述
你有一个数列a_1, a_2, \dots, a_na1,a2,…,an。你可以进行这样的一次操作,每次选择数列中其中一个数然后将其除22下取整,也就是选择一个数a_iai,变成\lfloor a_i/2 \rfloor⌊ai/2⌋。
请问对这些数字进行不超过kk次操作,这些数字的总和最小值可能是多少。
输入描述
第一行两个整数 n, k(1\leq n\leq 10^5, 0\leq k\leq 10^9)n,k(1≤n≤105,0≤k≤109),表示数字个数和操作个数。
接下来nn行,一共nn个整数a_1,a_2,\dots, a_na1,a2,…,an,保证1\leq a_i \leq 10^91≤ai≤109。
输出描述
一个数字表示答案。
样例输入 1
5 3 2 4 7 9 7样例输出 1
16虽然这个题很简单,就是k次队最大数进行除2操作。但是不得不说这个题的数据水了。
因为如果输入 1 1e9,会进行1e9次除2操作,会tle。但是我们知道,1e9只需要除32次就可以是0
所以我们用优先队列每次弹出最大值。但是如果队首为空的时候,就不需要再继续除2操作了。break输出即可。
#include<stdio.h> #include<iostream> #include<algorithm> #include<string.h> #include<string> #include<queue> #define PI 3.1415926 #define zero(x) (((x)>0?(x):-(x))<eps) using namespace std; typedef long long ll; const double eps = 1e-8; const int maxn = 1e5 + 100; int main() { int n, k; int u; scanf("%d%d", &n, &k); priority_queue<int>pq; for (int i = 1; i <= n; i++) { int u; scanf("%d", &u); pq.push(u); } while (k != 0) { u = pq.top(); if (u == 0) //队首等于0的时候,不需要再除2了 { break; } pq.pop(); u = u / 2; pq.push(u); k--; } ll sum = 0; while (!pq.empty()) { sum += pq.top(); pq.pop(); } printf("%lld\n", sum); return 0; }
CCPC-Wannafly Winter Camp Day5 (Div2, onsite) C Division 数据结构-优先队列
最新推荐文章于 2024-03-25 17:00:43 发布