Cod sursa(job #1307980)

Utilizator gabrieligabrieli gabrieli Data 3 ianuarie 2015 11:38:37
Problema Coduri Huffman Scor 70
Compilator cpp Status done
Runda Arhiva educationala Marime 1.73 kb
#include <cstdint>
#include <algorithm>
#include <fstream>
#include <vector>
#include <map>
using namespace std;

struct Node {
    uint64_t weight;
    int left;
    int right;
    
    Node(uint64_t weight, int left = 0, int right = 0)
    : weight {weight}, left {left}, right {right}
    {}
};

inline
int pop(const vector<Node>& Q, int& l1, const int r1, int& l2, const int r2) {
    int res;

    if (l1 < r1) {
        if (l2 < r2) {
            if (Q[l1].weight < Q[l2].weight) res = l1++;
            else res = l2++;
        }
        else res = l1++;
    }
    else res = l2++;
     
    return res;
}

uint64_t df(
        int node, map<int, vector<uint64_t>>& alphabet,
        const vector<Node>& data, uint64_t rep = 0, int h = 0) {
    if (data[node].left)
        return df(data[node].left, alphabet, data, rep << 1, h + 1) +
               df(data[node].right, alphabet, data, (rep << 1) + 1, h + 1);
    
    alphabet[h].push_back(rep);
    return data[node].weight * h;
}

int main() {
    ifstream fin("huffman.in");
    ofstream fout("huffman.out");
     
    int n; fin >> n;
    vector<Node> Q; Q.push_back(0);
    
    for (uint64_t x; n--; ) {
        fin >> x;
        Q.push_back(Node(x));
    }
    
    int l1 = 1, r1 = Q.size();
    int l2 = r1, r2 = r1;
    
    for (int l, r; r1 - l1 + r2 - l2 > 1;) {
        l = pop(Q, l1, r1, l2, r2);
        r = pop(Q, l1, r1, l2, r2);
        
        Q.push_back(Node(Q[l].weight + Q[r].weight, l, r));
        ++r2;
    }
    
    map<int, vector<uint64_t>> alphabet;
    fout << df(l2, alphabet, Q) << '\n';
    
    for (auto it = alphabet.rbegin(); it != alphabet.rend(); ++it)
        for (auto rep : it->second)
            fout << (it->first) << ' ' << rep << '\n';
    
    return 0;
}