Cod sursa(job #1715333)

Utilizator Cristian1997Vintur Cristian Cristian1997 Data 10 iunie 2016 12:52:52
Problema Coduri Huffman Scor 30
Compilator cpp Status done
Runda Arhiva educationala Marime 1.75 kb
using namespace std;
#include <cstdio>
#include <vector>
#include <algorithm>
#include <string>
#include <queue>
using ll = long long;
using uint = unsigned int;
using ull = unsigned long long;
using pii = pair<int, int>;
using pll = pair<ll, ll>;
#define Nmax 1000000

struct _node { int l, r; ll freq; } nodes[2 * Nmax];
int Q1[Nmax], Q2[Nmax];
int l1, r1, l2, r2;
int n, lg[Nmax];
ll codes[Nmax];

void read();
void getCodes(int, ll, int);
void write();
int getMin();

int main()
{
	int k, a, b;

	read();

	l1 = l2 = 0;
	r1 = r2 = -1;
	for (int i = 0; i < n; ++i) Q1[++r1] = i, nodes[i].l = nodes[i].r = -1;

	for (k = n; r1 - l1 + 1 + r2 - l2 + 1 > 1; Q2[++r2] = k)
	{
		++k;

		a = nodes[k].l = getMin();
		b = nodes[k].r = getMin();
		nodes[k].freq = nodes[a].freq + nodes[b].freq;
	}

	getCodes(k, 0, 0);

	write();

    return 0;
}


void read()
{
	freopen("huffman.in", "r", stdin);

	scanf("%d", &n);
	for (int i = 0; i < n; ++i) scanf("%d", &nodes[i].freq), nodes[i].l = nodes[i].r = -1;
}

void getCodes(int node, ll code, int l)
{
	if (nodes[node].l == -1) codes[node] = code, lg[node] = l;
	else
	{
		getCodes(nodes[node].l, code << 1, l + 1);
		getCodes(nodes[node].r, (code << 1) + 1, l + 1);
	}
}

void write()
{
	int i;
	ll lgCode;
	freopen("huffman.out", "w", stdout);

	for (lgCode = 0, i = 0; i < n; ++i)
		lgCode += 1LL * nodes[i].freq * lg[i];

	printf("%d\n", lgCode);

	for (i = 0; i < n; ++i)
		printf("%d %d\n", lg[i], codes[i]);
}


int getMin()
{
	int ret;

	if (l1 > r1) ret = Q2[l2], ++l2;
	else if (l2 > r2) ret = Q1[l1], ++l1;
	else if (nodes[Q1[l1]].freq < nodes[Q2[l2]].freq)
	{
		ret = Q1[l1];
		++l1;
	}
	else
	{
		ret = Q2[l2];
		++l2;
	}

	return ret;
}