Cod sursa(job #2734542)

Utilizator FischerMiguel Mini Fischer Data 1 aprilie 2021 08:16:54
Problema Coduri Huffman Scor 75
Compilator cpp-32 Status done
Runda Arhiva educationala Marime 2.81 kb
#include <bits/stdc++.h>
using namespace std;

const int maxn = 2e6 + 10;
int H[maxn][2];
int e = 1;
long long val[maxn];
int dist[maxn];
long long w[maxn];
int q1[maxn], q2[maxn];
int l1, l2, r1, r2;

vector<pair<int, long long>> res;
void bfs(int src) {
    val[src] = dist[src] = 0;
    queue<int> Q;
    Q.emplace(src);
    while (!Q.empty()) {
        int q = Q.front(); Q.pop();
        for (int i = 0; i < 2; ++i) {
            if (!H[q][i]) continue;
            dist[H[q][i]] = dist[q] + 1;
            val[H[q][i]] = val[q] * 2 + i;
            Q.emplace(H[q][i]);
        }
    }
}

bool is_asc(long long* l, long long* r) {
    int last = -2e9;
    for (long long* t = l; t != r; ++t) {
        if (last > *t) return 0;
        last = *t;
    }
    return 1;
}

int build(long long w[], int n) {
    for (int i = 1; i <= n; ++i) q1[r1++] = i;
    e = n + 1;
    bool who = 1;
    while (r1 - l1 + r2 - l2 > 1) {
        pair<int, int> q = {0, 0}; 
        long long temp = 2e18; 
        if (r1-l1 >= 2 && temp > w[q1[l1]] + w[q1[l1+1]]) {
            q = {q1[l1], q1[l1+1]};
            temp = w[q1[l1]] + w[q1[l1+1]];
        }
        if (r2-l2 >= 2 && temp > w[q2[l2]] + w[q2[l2+1]]) {
            q = {q2[l2], q2[l2+1]};
            temp = w[q2[l2]] + w[q2[l2+1]];
        }
        if (r1-l1 >= 1 && r2-l2 >= 1 && temp > w[q1[l1]] + w[q2[l2]]) {
            q = {q1[l1], q2[l2]};
            temp = w[q1[l1]] + w[q2[l2]];
        }
        
        w[e] = temp;
        H[e][0] = q.first;
        H[e][1] = q.second;
        
        if (r1-l1 >= 1 && q.first == q1[l1]) l1++;
        else l2++;
        
        if (r1-l1 >= 1 && q.second == q1[l1]) l1++;
        else l2++;
        
        if (who) {
            q2[r2++] = e++;
            if (l1 == r1) who ^= 1;
        } else {
            q1[r1++] = e++;
            if (l2 == r2) who ^= 1;
        }
    }   
    
    if (l1 != r1) return q1[l1];
    return q2[l2];
} 

int main() {
    freopen("huffman.in", "r", stdin);
    freopen("huffman.out", "w", stdout);
    int n;
    scanf("%d", &n);
    for (int i = 1; i <= n; ++i) {
        scanf("%lld", w+i);
    }
    using ii = pair<long long, int>;
    int root;
    if (!is_asc(w+1, w+n+1)) {
        priority_queue<ii> pq;
        for (int i = 1; i <= n; ++i) {
            pq.emplace(-w[i], e++);
        }
        while (pq.size() > 1) {
            auto a = pq.top(); pq.pop();
            auto b = pq.top(); pq.pop();
            H[e][0] = a.second;
            H[e][1] = b.second;
            pq.emplace(a.first + b.first, e++);
        }
        root = pq.top().second;
    } else {
        root = build(w, n);
    }
    bfs(root);
    long long ans = 0;
    for (int i = 1; i <= n; ++i) ans += dist[i] *1ll * w[i];
    printf("%lld\n", ans);
    for (int i = 1; i <= n; ++i) {
        printf("%d %lld\n", dist[i], val[i]);
    }
    return 0;
}