HDU 5884 Sort——二分+O(n)哈弗曼树

两个队列搞一搞就搞出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;
}

 

    原文作者:哈夫曼树
    原文地址: https://blog.csdn.net/hao_zong_yin/article/details/82015945
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞