Cod sursa(job #1872752)

Utilizator oldatlantianSerban Cercelescu oldatlantian Data 8 februarie 2017 16:12:50
Problema Coduri Huffman Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2.29 kb
#include <bits/stdc++.h>
#define gnu_log2(X) ((unsigned) (8*sizeof (unsigned long long) - __builtin_clzll((X)) - 1))
using namespace std;

typedef long long i64;

const int BMAX = 1 << 17,
          NMAX = 1e6 + 5;

struct Nod {
    i64 w, cod;
    int a, b, len; };

vector<Nod> arb;
int n;

char buff[BMAX];

inline char nextch() {
    static int bp = BMAX;

    if (bp == BMAX) {
        fread(buff, 1, BMAX, stdin);
        bp = 0; }

    return buff[ bp++ ]; }

void get(int &arg) {
    char ch;
    do {
        ch = nextch(); }
    while (ch < '0' || '9' < ch);
    arg = 0;
    do {
        arg = arg * 10 + ch - '0';
        ch = nextch(); }
    while ('0' <= ch && ch <= '9'); }

void get(i64 &arg) {
    char ch;
    do {
        ch = nextch(); }
    while (ch < '0' || '9' < ch);
    arg = 0;
    do {
        arg = arg * 10 + ch - '0';
        ch = nextch(); }
    while ('0' <= ch && ch <= '9'); }

void dfs(int nod) {
    if (nod < n) return;
    arb[arb[nod].a].cod = arb[nod].cod << 1;
    arb[arb[nod].a].len = arb[nod].len + 1;
    dfs(arb[nod].a);
    arb[arb[nod].b].cod = (arb[nod].cod << 1) | 1;
    arb[arb[nod].b].len = arb[nod].len + 1;
    dfs(arb[nod].b); }

int main() {
    freopen("huffman.in", "r", stdin);
    freopen("huffman.out", "w", stdout);
    deque<int> main_q, aux_q;
    int t, a, b;
    i64 ant;

    ant = 0;

    get(n);
    arb.resize(n);
    for (auto &i: arb) {
        i = {0, 0, -1, -1};
        get(i.w); }

    for (int i = 0; i < n; ++i)
        main_q.push_back(i);

    while (main_q.size() + aux_q.size() > 1) {
        while (!aux_q.empty() && (arb[aux_q.front()].w <= arb[main_q.front()].w || main_q.empty())) {
            main_q.push_front(aux_q.front());
            aux_q.pop_front(); }
        a = main_q.front(), main_q.pop_front();

        while (!aux_q.empty() && (arb[aux_q.front()].w <= arb[main_q.front()].w || main_q.empty())) {
            main_q.push_front(aux_q.front());
            aux_q.pop_front(); }
        b = main_q.front(), main_q.pop_front();

        aux_q.push_back(arb.size());
        arb.push_back({arb[a].w + arb[b].w, 0, a, b}); }

    dfs(arb.size() - 1);

    for (int i = 0; i < n; ++i)
        ant+= arb[i].w * arb[i].len;

    printf("%lld\n", ant);
    for (int i = 0; i < n; ++i)
        printf("%d %lld\n", arb[i].len, arb[i].cod);

    return 0; }