版权声明:欢迎大家转载,转载请注明出处 https://blog.csdn.net/hao_zong_yin/article/details/82015945
两个队列搞一搞就搞出O(n)的哈弗曼树了
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
typedef long long ll;
const int maxn = 1e5 + 10;
char c;
inline void input(int &x) {
x = 0;
while ((c = getchar()) < '0' || c > '9');
while ('0' <= c && c <= '9') x = x*10+(c-'0'), c = getchar();
}
int T, n, t, a[maxn];
struct Queue {
int l, r;
ll data[maxn];
}q1, q2;
bool judge(int k) {
q1.l = 1, q1.r = n;
q2.l = 1, q2.r = 0;
ll ans = 0, temp = 0;
int x = (n-1)%(k-1), y = (n-1)/(k-1);
if (x) {
for (int i = 1; i <= x + 1; i++) temp += q1.data[q1.l++];
ans += temp;
q2.data[++q2.r] = temp;
}
while (y--) {
temp = 0;
for (int i = 1; i <= k; i++) {
if (q2.l > q2.r) temp += q1.data[q1.l++];
else if (q1.l > q1.r) temp += q2.data[q2.l++];
else if (q1.l <= q1.r && q2.l <= q2.r) {
if (q1.data[q1.l] <= q2.data[q2.l]) temp += q1.data[q1.l++];
else temp += q2.data[q2.l++];
}
}
ans += temp;
q2.data[++q2.r] = temp;
}
return ans <= t;
}
void solve() {
input(n); input(t);
for (int i = 1; i <= n; i++) input(a[i]);
sort(a+1, a+1+n);
for (int i = 1; i <= n; i++) q1.data[i] = a[i];
int l = 2, r = n;
while (l < r) {
int mid = (l+r)>>1;
if (judge(mid)) r = mid;
else l = mid+1;
}
printf("%d\n", r);
}
int main() {
input(T);
while (T--) solve();
return 0;
}