Cod sursa(job #1478344)

Utilizator lflorin29Florin Laiu lflorin29 Data 28 august 2015 14:21:50
Problema Coduri Huffman Scor 70
Compilator cpp Status done
Runda Arhiva educationala Marime 2.65 kb
#include <bits/stdc++.h>
using namespace std;

struct hufm{
    long long ap;
    int sons[2];
};

const int nofSimbols = (int)2 * 1e6 + 5;
const long long nofAp = (int) 1e18;
long long n;
hufm simb[nofSimbols];
long long tLen;
long long lg[nofSimbols], rep[nofSimbols];
queue < pair <long long, int > > que[2];

class InputReader {
    public:
        InputReader() {}
        InputReader(const char *file_name) {
            input_file = fopen(file_name, "r");
            cursor = 0;
            fread(buffer, SIZE, 1, input_file);
        }
        inline InputReader &operator >>(long long &n ) {
            while(buffer[cursor] < '0' || buffer[cursor] > '9') {
                advance();
            }
            n = 0;
            while('0' <= buffer[cursor] && buffer[cursor] <= '9') {
                n = n * 10 + buffer[cursor] - '0';
                advance();
            }
            return *this;
        }
    private:
        FILE *input_file;
        static const int SIZE = 1 << 17;
        int cursor;
        char buffer[SIZE];
        inline void advance() {
            ++ cursor;
            if(cursor == SIZE) {
                cursor = 0;
                fread(buffer, SIZE, 1, input_file);
            }
        }
};

void read(){
    InputReader fin ("huffman.in");
    fin >> n;
    for (int i = 1; i <= n; ++i){
        long long now;
        fin >> now;
        simb[i].ap = now;
        que[0].push({now, i});
    }
}

void makeTree(){
    int kNod = n;
    while (que[0].size() + que[1].size() > 1){
        ++kNod;
        for (int son = 0; son < 2; ++son){
            bool from = 0;
            long long now = -1;
            if (que[0].size())
                now = que[0].front().first;
            if (que[1].size() and (que[1].front().first < now or now == -1) )
                now = que[1].front().first, from = 1;
            simb[kNod].sons[son] = que[from].front().second;
            simb[kNod].ap += que[from].front().first;
            que[from].pop();
        }
        que[1].push({simb[kNod].ap, kNod});
    }
}

inline void dfs (int pos, long long code, int level){
    if (simb[pos].sons[0]){
        dfs(simb[pos].sons[0], code << 1LL, level + 1);
        dfs(simb[pos].sons[1], (code << 1LL) | 1LL, level + 1);
        return;
    }
    lg[pos] = level;
    rep[pos] = code;
    tLen += simb[pos].ap * level;
}

void solve(){
    ofstream fout ("huffman.out");
    dfs(2 * n - 1, 0, 0);
    fout << tLen << "\n";
    for (int i = 1; i <= n; ++i)
        fout << lg[i] << " " << rep[i] << "\n";
}

int main(){
    read();
    makeTree();
    solve();
}