Cod sursa(job #754271)

Utilizator darrenRares Buhai darren Data 1 iunie 2012 12:05:03
Problema Coduri Huffman Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.65 kb
#include <cstdio>
#include <fstream>
#include <algorithm>

using namespace std;

const int SIZE = 1000002;

ifstream fin("huffman.in");

char parse[1 << 18];
int now;
inline void verify()
{
	if (parse[now] == 0)
	{
		fin.get(parse, 1 << 18, '\0');
		now = 0;
	}
}
int get()
{
	int number = 0;
	while (!(parse[now] >= '0' && parse[now] <= '9'))
	{
		++now;
		verify();
	}
	while (parse[now] >= '0' && parse[now] <= '9')
	{
		number = number * 10 + (parse[now] - '0');
		++now;
		verify();
	}
	return number;
}

int N, F[SIZE];
int Q[2][SIZE], beg[2], end[2];
int nodnow;
long long val[2 * SIZE];
int son[2 * SIZE][2], leng[SIZE];
long long bin[SIZE], result;

void Dfs(int nod, long long val, int len)
{
	if (son[nod][0])
	{
		Dfs(son[nod][0], val * 2, len + 1);
		Dfs(son[nod][1], val * 2 + 1, len + 1);
		return;
	}
	leng[nod] = len;
	bin[nod] = val;
}

int main()
{
	freopen("huffman.out", "w", stdout);
	verify();
	
	N = get();
	
	beg[0] = 1, end[0] = 0;
	for (int i = 1; i <= N; ++i)
	{
		F[i] = get();
		Q[0][++end[0]] = i;
		val[i] = F[i];
	}
	
	nodnow = N;
	
	beg[1] = 1, end[1] = 0;
	
	int now, where;
	while (end[0] + end[1] - beg[0] - beg[1] >= 0)
	{
		++nodnow;
		for (int i = 0; i < 2; ++i)
		{
			now = -1;
			for (int j = 0; j < 2; ++j)
				if (beg[j] <= end[j] && (now == -1 || val[now] > val[Q[j][beg[j]]]))
				{
					now = Q[j][beg[j]];
					where = j;
				}
			++beg[where];
			
			val[nodnow] += val[now];
			son[nodnow][i] = now;
		}
		
		Q[1][++end[1]] = nodnow;
	}
	Dfs(nodnow, 0, 0);
	
	for (int i = 1; i <= N; ++i)
		result += 1LL * F[i] * leng[i];
	printf("%lld\n", result);
	for (int i = 1; i <= N; ++i)
		printf("%d %lld\n", leng[i], bin[i]);
	
	fin.close();
}