Cod sursa(job #2927585)

Utilizator MR0L3eXMaracine Constantin Razvan MR0L3eX Data 20 octombrie 2022 21:38:08
Problema Coduri Huffman Scor 90
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 3.04 kb
/**
 *    author:  R0L3eX
 *    created: 20.10.2022 19:11:53
**/

#include "bits/stdc++.h"

#if defined(ONPC)
#include "bits/debug.h"
#endif
 
using namespace std;
 
using ll = long long;
using ld = long double;
using cd = complex<ld>;
 
using pi = pair<int, int>;
using pl = pair<ll, ll>;
using pd = pair<ld, ld>;
 
using vi = vector<int>;
using vd = vector<ld>;
using vl = vector<ll>;
using vpi = vector<pi>;
using vpl = vector<pl>;
using vcd = vector<cd>;
 
template<class T> using pq = priority_queue<T>;
template<class T> using pqg = priority_queue<T, vector<T>, greater<T>>;
 
#define FOR(i, a, b) for (int i=a; i<(b); i++)
#define F0R(i, a) for (int i=0; i<(a); i++)
#define FORd(i,a,b) for (int i = (b)-1; i >= a; i--)
#define F0Rd(i,a) for (int i = (a)-1; i >= 0; i--)
#define trav(a,x) for (auto& a : x)
#define uid(a, b) uniform_int_distribution<int>(a, b)(rng)
 
#define sz(x) (int)(x).size()
#define mp make_pair
#define pb push_back
#define fi first
#define se second
#define lb lower_bound
#define ub upper_bound
#define all(x) x.begin(), x.end()
#define rall(x) x.rbegin(), x.rend()
#define ins insert
 
template<class T> bool ckmin(T& a, const T& b) { return b < a ? a = b, 1 : 0; }
template<class T> bool ckmax(T& a, const T& b) { return a < b ? a = b, 1 : 0; }
 
mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
 
const int MOD = 1e9 + 7;
const int INF = 1e9;
const int mxN = 1e6; 
const char nl = '\n';

vl frq, cod;
vi L, R, len;
queue<int> Q1, Q2;

void init(int n) {
    frq = vl(2 * n + 2);
    cod = vl(2 * n + 2);
    len = vi(2 * n + 2);
    L = vi(2 * n + 2, -1);
    R = vi(2 * n + 2,  -1);
}

ll getNext(queue<int> &Q1, queue<int> &Q2) {
    int ans = 0;
    if (Q1.empty()) {
        ans = Q2.front();
        Q2.pop();
    } else if (Q2.empty()) {
        ans = Q1.front();
        Q1.pop();
    } else if (frq[Q1.front()] < frq[Q2.front()]) {
        ans = Q1.front();
        Q1.pop();
    } else {
        ans = Q2.front();
        Q2.pop();
    }
    return ans;
} 

int build(int n) {
    F0R(i, n) {
        Q1.push(i);
    }
    int node = n - 1;
    while (sz(Q1) + sz(Q2) > 1) {
        int node0 = getNext(Q1, Q2);
        int node1 = getNext(Q1, Q2);
        node++;
        frq[node] = frq[node0] + frq[node1];
        L[node] = node0;
        R[node] = node1;
        Q2.push(node);
    }
    return Q2.front();
}

ll tot_sum = 0;
void dfs(int node, ll cur_cod, int cur_len) {
    // if we are not in a leaf
    if (L[node] != -1 && R[node] != -1) {
        dfs(L[node], 2 * cur_cod, cur_len + 1);
        dfs(R[node], 2 * cur_cod + 1, cur_len + 1);
    } else {
        cod[node] = cur_cod;
        len[node] = cur_len;
        tot_sum += frq[node] * len[node];
    }
}

int main() {
    // ios::sync_with_stdio(false);
    // std::cin.tie(nullptr);

    ifstream fin("huffman.in");
    ofstream fout("huffman.out");

    int n;
    fin >> n;
    init(n);
    F0R(i, n) fin >> frq[i];
    int root = build(n);
    dfs(root, 0, 0);
    fout << tot_sum << nl;
    F0R(i, n) {
        fout << len[i] << ' ' << cod[i] << nl;
    }
    return 0;
}