Cod sursa(job #1564970)

Utilizator TimitocArdelean Andrei Timotei Timitoc Data 10 ianuarie 2016 08:56:29
Problema Coduri Huffman Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.43 kb
#include <iostream>
#include <cstdio>
#define MAXN 1000050

using namespace std;

int n, a[MAXN];
short nrpre[2*MAXN];
int nq; /// intern cardinal
int inda, indi;
long long sol, calc[2*MAXN], intern[MAXN];

struct p
{
    int tata, bit;
    p(int tata=0, int bit=0) : tata(tata), bit(bit) { }
} parent[2*MAXN];

void citire()
{
	scanf("%d", &n);
	for (int i = 1; i <= n; ++i)
		scanf("%d", &a[i]);
	inda = 1, indi = 1;
}

long long getMin(int tata, int bit)
{
	if (indi > nq || inda <= n && a[inda] <= intern[indi]) {
		parent[inda] = p(tata, bit);
		return a[inda++];
	}
	else {
		parent[indi+n] = p(tata, bit);
		return intern[indi++];
	}
}

void solve()
{
	for (int i = n+1; i < 2*n; i++) {
		long long val1 = getMin(i, 0);
		long long val2 = getMin(i, 1);
        intern[++nq] = val1+val2;
        sol += val1 + val2;
	}
}

void get(int nod, int &nr, long long &val)
{
	if (nrpre[nod]) {
        nr = nrpre[nod];
        val = calc[nod];
        return;
	}
	if (nod == 2*n-1) {
        nr = 0;
        val = 0;
        return ;
	}
	get(parent[nod].tata, nr, val);
	nr++;
	val = (val << 1) + parent[nod].bit;
	calc[nod] = val;
	nrpre[nod] = nr;
}

void print()
{
	printf("%lld\n", sol);
	for (int i = 1; i <= n; i++) {
		int nr; long long val;
        get(i, nr, val);
        printf("%d %lld\n", nr, val);
	}

}

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

    citire();
    solve();
    print();

    return 0;
}