Cod sursa(job #2734583)

Utilizator FischerMiguel Mini Fischer Data 1 aprilie 2021 09:02:42
Problema Coduri Huffman Scor 0
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.71 kb
#include <bits/stdc++.h>
#pragma GCC optimization ("O3")
using namespace std;
	
const int maxn = 2e6 + 5;
int H[maxn][2], dist[maxn];
int e = 1;
long long val[maxn], w[maxn];

void dfs(int x, int p) {
    if (!x) return;
    val[x] = 2 * val[p] + 1;
    dist[x] = dist[p] + 1;
    dfs(H[x][0], x);
    dfs(H[x][1], x);
}
	
int build(long long w[], int n) {
    deque<int> a(n), b;
    iota(a.begin(), a.end(), 1);
    e = n + 1;
    while (a.size() + b.size() > 1) {
        pair<int, int> q = {0, 0}; 
        long long temp = 2e18; 
        if (a.size() >= 2 && temp > w[a[0]] + w[a[1]]) {
            q = {a[0], a[1]};
            temp = w[a[0]] + w[a[1]];
        }
        if (b.size() >= 2 && temp > w[b[0]] + w[b[1]]) {
            q = {b[0], b[1]};
            temp = w[b[0]] + w[b[1]];
        }
        if (b.size() && temp > w[a[0]] + w[b[0]]) {
            q = {a[0], b[0]};
            temp = w[a[0]] + w[b[0]];
        }
        w[e] = temp;
        H[e][0] = q.first;
        H[e][1] = q.second;
        if (a.size() >= 1 && q.first == a[0]) a.pop_front();
        else b.pop_front();
        if (a.size() >= 1 && q.second == a[0]) a.pop_front();
        else b.pop_front();
        b.emplace_back(e++);
        if (a.empty()) swap(a, b);
    }   
    return a[0];
} 
	
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);
    int root = build(w, n);
    dfs(H[root][0], root);
    dfs(H[root][1], root);
    long long ans = 0;
    for (int i = 1; i <= n; ++i) ans += dist[i] * w[i];
    printf("%lld\n", ans);
    for (int i = 1; i <= n; ++i) {
        printf("%d %lld\n", dist[i], val[i]);
    }
    return 0;
}