Cod sursa(job #1503133)

Utilizator stefanzzzStefan Popa stefanzzz Data 15 octombrie 2015 16:53:30
Problema Coduri Huffman Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.88 kb
#include <stdio.h>
#include <iostream>
#define MAXN 1000005
#define MAXBUF 65536
using namespace std;

struct Node {
    long long val;
    int sons[2];
} tree[2 * MAXN];

char buf[MAXBUF];
long long totLg;
int nt, x, cnt;
pair<int, long long> sol[MAXN];
int n, ind1 = 1, ind2;

inline int extractMin() {
    if(ind1 > n || (ind2 <= nt && tree[ind2].val < tree[ind1].val))
        return (ind2++);

    return (ind1++);
}

void DFS(int u, int lvl, long long vl) {
    if(tree[u].sons[0] == 0 && tree[u].sons[1] == 0) {
        sol[u] = make_pair(lvl, vl);
        totLg += 1LL * tree[u].val * sol[u].first;
        return;
    }
    if(tree[u].sons[0])
        DFS(tree[u].sons[0], lvl + 1, vl << 1);
    if(tree[u].sons[1])
        DFS(tree[u].sons[1], lvl + 1, (vl << 1) + 1);
}

inline int getInt() {
    int ans = 0;
    while(buf[cnt] < '0' || buf[cnt] > '9')
        if(++cnt == MAXBUF) {
            fread(buf, 1, sizeof(buf), stdin);
            cnt = 0;
        }

    while(buf[cnt] >= '0' && buf[cnt] <= '9') {
        ans = ans * 10 + buf[cnt] - '0';
        if(++cnt == MAXBUF) {
            fread(buf, 1, sizeof(buf), stdin);
            cnt = 0;
        }
    }

    return ans;
}

int main()
{
    freopen("huffman.in", "r", stdin);
    freopen("huffman.out", "w", stdout);

    fread(buf, 1, sizeof(buf), stdin);

    n = getInt();
    for(int i = 1; i <= n; i++) {
        x = getInt();
        tree[++nt].val = x;
    }
    ind2 = n + 1;

    for(int i = 1; i < n; i++) {
        int x1 = extractMin();
        int x2 = extractMin();

        tree[++nt].val = tree[x1].val + tree[x2].val;
        tree[nt].sons[0] = x1;
        tree[nt].sons[1] = x2;
    }

    DFS(nt, 0, 0);

    printf("%lld\n", totLg);

    for(int i = 1; i <= n; i++)
        printf("%d %lld\n", sol[i].first, sol[i].second);

    return 0;
}