Cod sursa(job #1478349)

Utilizator lflorin29Florin Laiu lflorin29 Data 28 august 2015 14:26:58
Problema Coduri Huffman Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2.08 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];

char ax[nofSimbols >> 8];
int pz;
#define dim 19

inline void cit(long long &x) {
    x = 0;
    while (ax[pz] < '0' || ax[pz] > '9')
        if (++pz == dim)
            fread(ax, 1, dim, stdin), pz = 0;
    while (ax[pz] >= '0' && ax[pz] <= '9') {
        x = x * 10 + ax[pz] - '0';
        if (++pz == dim)
            fread(ax, 1, dim, stdin), pz = 0;
    }
}
void read(){
    freopen ("huffman.in", "r", stdin);
    cit(n);
    for (int i = 1; i <= n; ++i){
        long long now;
        cit(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(){
    freopen ("huffman.out", "w", stdout);
    dfs(2 * n - 1, 0, 0);
    printf ("%lld\n", tLen);
    for (int i = 1; i <= n; ++i)
        printf ("%lld %lld\n", lg[i], rep[i]);
}

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