Cod sursa(job #1308000)

Utilizator gabrieligabrieli gabrieli Data 3 ianuarie 2015 12:12:42
Problema Coduri Huffman Scor 70
Compilator cpp Status done
Runda Arhiva educationala Marime 1.69 kb
#include <cstdint>
#include <algorithm>
#include <fstream>
#include <vector>
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, vector<pair<int, 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[node] = {h, 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;
    }
    
    
    vector<pair<int, uint64_t>> alphabet(r1);
    fout << df(l2, alphabet, Q) << '\n';
    
    for (auto it = alphabet.begin() + 1; it != alphabet.end(); ++it)
        fout << (it->first) << ' ' << (it->second) << '\n';
    
    return 0;
}