Cod sursa(job #1662535)

Utilizator ArkinyStoica Alex Arkiny Data 24 martie 2016 20:38:51
Problema Coduri Huffman Scor 80
Compilator cpp Status done
Runda Arhiva educationala Marime 2.47 kb
#include<fstream>
#include<queue>
using namespace std;

ifstream in("huffman.in");
ofstream out("huffman.out");

int N;

struct Node
{
	int f1, f2;
	long long val;
};

Node arb[3000010];

pair<int, long long> r[1000010];

int t = 0;
long long sol = 0;

int q[2][2000000], q1_s = 1, q1_f = 0, q2_s = 1, q2_f = 0;
int s = 0;

void DFS(int i, long long nr, long long e)
{
	if (arb[i].f1 != 0)
	{
		DFS(arb[i].f1, nr + 1, e << 1);
		DFS(arb[i].f2, nr + 1, (e << 1) | 1LL);
	}
	else
	{
		r[i] = make_pair(nr, e);
		sol += nr*arb[i].val;
	}
}

int main()
{
	in >> N;

	for (int i = 1;i <= N;++i)
	{
		int e;
		in >> e;
		arb[++t].f1 = 0, arb[t].f2 = 0, arb[t].val = e;
		q[0][++q1_f] = t;
	}

	int e1, e2, size1, size2, op;
	long long min;
	while (!(q1_f-q1_s+1 == 1 && q2_f<q2_s))
	{
		int s1 = (s + 1) % 2;
		if (q1_f < q1_s)
			size1 = 0;
		else
			size1 = q1_f - q1_s + 1;

		if (q2_f < q2_s)
			size2 = 0;
		else
			size2 = q2_f - q2_s + 1;
		if (size2 == 0)
		{
			e1 = q[s][q1_s];
			++q1_s;
			e2 = q[s][q1_s];
			++q1_s;
		}
		else if (size1 == 1 || size2 == 1)
		{
			e1 = q[s][q1_s];
			e2 = q[s1][q2_s];
			min = arb[e1].val + arb[e2].val;
			if (size1 != 1 && size2 == 1)
			{
				if (arb[q[s][q1_s]].val + arb[q[s][q1_s+1]].val < min)
					e1 = q[s][q1_s], e2 = q[s][q1_s+1], q1_s+=2;
				else
					q1_s++,q2_s++;
			}
			else if (size1 == 1 && size2 != 1)
			{
				if (arb[q[s1][q2_s]].val + arb[q[s1][q2_s+1]].val < min)
					e1 = q[s1][q2_s], e2 = q[s1][q2_s+1], q2_s+=2;
				else
					q1_s++, q2_s++;
			}
			else
			{
				q1_s++, q2_s++;
			}
		}
		else
		{
			e1 = q[s][q1_s];
			e2 = q[s1][q2_s];
			min = arb[e1].val + arb[e2].val;
			op = 1;

			if (arb[q[s][q1_s]].val + arb[q[s][q1_s+1]].val < min)
				op = 2, min = arb[q[s][q1_s]].val + arb[q[s][q1_s+1]].val;
			if (arb[q[s1][q2_s]].val + arb[q[s1][q2_s+1]].val < min)
				op = 3;

			if (op == 1)
			{
				q1_s++, q2_s++;
			}
			else if (op == 2)
			{
				e1 = q[s][q1_s];
				e2 = q[s][q1_s+1];
				q1_s += 2;
			}
			else
			{
				e1 = q[s1][q2_s];
				e2 = q[s1][q2_s+1];
				q2_s += 2;
			}

		}

		arb[++t].f1 = e1;
		arb[t].f2 = e2;
		arb[t].val = arb[e1].val + arb[e2].val;

		q[s1][++q2_f] = t;

		if (q1_f<q1_s)
			s = (s + 1) % 2,swap(q1_s,q2_s),swap(q1_f,q2_f);
	}
	DFS(q[s][q1_s], 0, 0);
	out << sol << '\n';

	for (int i = 1;i <= N;++i)
		out << r[i].first << " " << r[i].second << '\n';

	return 0;
}