Cod sursa(job #2266161)

Utilizator BogdanisarBurcea Bogdan Madalin Bogdanisar Data 22 octombrie 2018 12:49:51
Problema Coduri Huffman Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.63 kb
#include <bits/stdc++.h>
  
using namespace std;
  
#if 1
    #define pv(x) cout<<#x<<" = "<<(x)<<"; ";cout.flush()
    #define pn cout<<endl
#else
    #define pv(x)
    #define pn
#endif
  
// #if 1
#ifdef INFOARENA
    ifstream in("huffman.in");
    ofstream out("huffman.out");
#else
    #define in cin
    #define out cout
#endif
  
using ll = long long;
using ull = unsigned long long;
using uint = unsigned int;
using ld = long double;
using pii = pair<int,int>;
using pll = pair<ll,ll>;
using pld = pair<ld, ld>;
#define pb push_back
const long double PI = 3.14159265358979323846264338327950288419716939937510582097494459230781640628620899862;
const int inf_int = 1e9 + 5;
const ll inf_ll = 1e18 + 5;
const int NMax = 1e6 + 5;
const int mod = 1e9 + 7;
const int dx[] = {-1,0,0,+1}, dy[] = {0,-1,+1,0};

struct arbNode {
    ll sum;
    int st, dr;
    arbNode(ll _sum = 0, int _st = 0, int _dr = 0) {
        sum = _sum;
        st = _st;
        dr = _dr;
    }
} node[2*NMax];

int getMin(queue<int>& q1, queue<int>& q2) {
    assert(q1.size() + q2.size() != 0);

    int ans = 0;
    if (q1.empty() || (q2.size() && node[q2.front()].sum < node[q1.front()].sum)) {
        ans = q2.front();
        q2.pop();
    }
    else {
        ans = q1.front();
        q1.pop();
    }

    return ans;
}

void dfs(int curr, int len, ll decimal, vector<pair<int,ll>>& ans) {
    assert((node[curr].st == 0 && node[curr].dr == 0) || (node[curr].st != 0 && node[curr].dr != 0));
    if (node[curr].st == 0) {
        ans[curr] = {len,decimal};
        return;
    }

    dfs(node[curr].st, len + 1, decimal<<1, ans);
    dfs(node[curr].dr, len + 1, (decimal<<1) + 1, ans);
}

int main() {
    cin.sync_with_stdio(false);
    cin.tie(0);
    
    int N, numNode = 0;
    in >> N;
    assert(N > 1);
    queue<int> interior, exterior;
    for (int i = 1; i <= N; ++i) {
        ll freq;
        in >> freq;
        node[++numNode] = arbNode(freq, 0, 0);
        exterior.push(numNode);
    }

    ll total = 0;
    for (int i = 1; i <= N-1; ++i) {
        int min1 = getMin(interior, exterior);
        int min2 = getMin(interior, exterior);

        node[++numNode] = arbNode(node[min1].sum + node[min2].sum, min1, min2);
        interior.push(numNode);
        total += node[min1].sum + node[min2].sum;
    }
    assert(exterior.size() == 0 && interior.size() == 1);

    vector<pair<int,ll>> ans(N+1);
    dfs(interior.front(), 0, 0LL, ans);
    out << total << '\n';
    for (int i = 1; i <= N; ++i) {
        out << ans[i].first << ' ' << ans[i].second << '\n';
    }
    
    return 0;
}