Cod sursa(job #1872722)

Utilizator oldatlantianSerban Cercelescu oldatlantian Data 8 februarie 2017 15:42:54
Problema Coduri Huffman Scor 70
Compilator cpp Status done
Runda Arhiva educationala Marime 2.1 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;

    inline bool operator < (const Nod &arg) const { // God forgive me!
        return w > arg.w; } };

vector<Nod> arb;
int n;

char buff[BMAX];

struct Cmp {
    inline bool operator () (const int &a, const int &b) {
        return arb[a].w > arb[b].w; } };

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);
    priority_queue<int, vector<int>, Cmp> pq;
    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)
        pq.push(i);

    while (pq.size() > 1) {
        a = pq.top(), pq.pop();
        b = pq.top(), pq.pop();

        arb.push_back({arb[a].w + arb[b].w, 0, a, b});
        pq.push(arb.size() - 1); }

    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; }