Cod sursa(job #1397090)

Utilizator SmarandaMaria Pandele Smaranda Data 23 martie 2015 11:37:29
Problema Coduri Huffman Scor 0
Compilator cpp Status done
Runda Arhiva educationala Marime 2.9 kb
#include <cstdio>
#include <utility>
#include <fstream>
#include <vector>

using namespace std;

const int N = 1000008, SIZE = 32000;

class myIfstream {
private :
    int cursor;
    char buffer [SIZE];
    FILE *input;
    void advance () {
        ++ cursor;
        if (cursor == SIZE) {
            cursor = 0;
            fread (buffer, 1, SIZE, input);
        }
    }
public :
    myIfstream ();
    myIfstream (const char *inputName) {
        input = fopen (inputName, "r");
        cursor = 0;
        fread (buffer, 1, SIZE, input);
    }
    myIfstream &operator >> (long long &value) {
        value = 0;
        while (!(buffer [cursor] >= '0' && buffer [cursor] <= '9'))
            advance();
        while (buffer [cursor] >= '0' && buffer [cursor] <= '9') {
            value = value * 10 + buffer [cursor] - '0';
            advance();
        }
        return *this;
    }
};

long long a [N], b [N], n, sol [N];
int nodb [N], lg [N];

vector <pair <int, int> > graph [63 * N + 2];

myIfstream fin ("huffman.in");

void dfs (int x, long long value, int level) {
    vector <pair <int, int> > :: iterator it;

    if (x <= n) {
        lg [x] = level + 1;
        sol [x] = value;
    }
    for (it = graph [x].begin (); it != graph [x].end (); ++ it)
        dfs ((*it).first, value | (((*it).second) << (level + 1)), level + 1);
}

int main () {
    int i, u, i1, i2, poz;
    long long  k, ans = 0, l;

    //freopen ("huffman.in", "r", stdin);
    freopen ("huffman.out", "w", stdout);

    fin >> n;
  //  scanf ("%lld", &n);
    for (i = 1; i <= n; i ++)
       // scanf ("%lld", &a [i]);
       fin >> a [i];

    l = n;
    b [1] = a [1] + a [2];
    ans = ans + b [1];
    nodb [1] = ++ l;
    graph [l].push_back (make_pair (1, 0));
    graph [l].push_back (make_pair (2, 1));
    i1 = 3;
    i2 = u = 1;
    while (i1 <= n || i2 <= u) {
        for (i = 1; i <= 2; i ++) {
            k = (1ll << 62) - 1;
            poz = -1;
            if (i1 <= n && a [i1] < k) {
                k = a [i1];
                poz = 1;
            }
            if (i2 <= u && b [i2] < k) {
                k = b [i2];
                poz = 2;
            }
            if (poz != -1) {
                b [u + 1] = b [u + 1] + k;
                nodb [u + 1] = l + 1;
                if (poz == 1) {
                    graph [l + 1].push_back (make_pair (i1, i - 1));
                    ++ i1;
                }
                if (poz == 2) {
                    graph [l + 1].push_back (make_pair (nodb [i2], i - 1));
                    ++ i2;
                }
            }
        }
        if (poz == -1)
            break;
        ++ u; ++ l;
        ans = ans + b [u];
    }
    printf ("%lld\n", ans);
    dfs (nodb [u], 0, -1);
    for (i = 1; i <= n; i ++)
        printf ("%d %lld\n", lg [i], sol [i]);
    return 0;
}