Cod sursa(job #1979598)

Utilizator mouse_wirelessMouse Wireless mouse_wireless Data 10 mai 2017 21:47:35
Problema Coduri Huffman Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2.28 kb
#include <cstdio>
#include <cmath>
#include <vector>
#include <algorithm>
#include <cassert>
#include <cstring>
#include <climits>
using namespace std;
typedef long long LL;

#ifdef INFOARENA
#define ProblemName "huffman"
#endif

#define MCONCAT(A, B) A B
#ifdef ProblemName
#define InFile MCONCAT(ProblemName, ".in")
#define OuFile MCONCAT(ProblemName, ".out")
#else
#define InFile "fis.in"
#define OuFile "fis.out"
#endif

#define MAXBUF 20000000
char physicalInput[MAXBUF], *head = physicalInput;

LL nextLL() {
	LL rez = 0;
	while ((*head) < '0' || (*head) > '9')
		++head;
	do {
		rez = rez * 10 + (*head) - '0';
		++head;
	} while ((*head) >= '0' && (*head) <= '9');
	return rez;
}

#define MAXN 1000010

struct nod {
	LL cost;
	nod *parent;
	int bit;
} v[MAXN], others[MAXN << 1];

int N;

pair<int, LL> repr[MAXN];

void setRepr(int i) {
	nod *p = &v[i];
	while (p->parent != NULL) {
		++repr[i].first;
		repr[i].second = (repr[i].second << 1) | p->bit;
		p = p->parent;
	}
	LL o = 0;
	for (int j = 0; j < repr[i].first; ++j) {
		o = (o << 1) | (repr[i].second & 1);
		repr[i].second >>= 1;
	}
	repr[i].second = o;
}

#define PUSHNODE() {\
others[qe].cost = p0->cost + p1->cost;\
p0->parent = &others[qe]; p0->bit = 0;\
p1->parent = &others[qe]; p0->bit = 1;\
++qe;\
}

int main() {
	assert(freopen(InFile, "r", stdin));
	assert(freopen(OuFile, "w", stdout));
	int aux = fread(physicalInput, 1, MAXBUF, stdin);
	physicalInput[aux] = 0;
	N = (int)nextLL();
	for (int i = 0; i < N; ++i)
		v[i].cost = nextLL();
	int i0 = 0, i1 = 0, qe = 0;
	while (i0 < N) {
		nod *p0;
		if (i1 < qe && others[i1].cost < v[i0].cost) {
			p0 = &others[i1];
			i1++;
		}
		else {
			p0 = &v[i0];
			i0++;
		}
		nod *p1;
		if ((i0 >= N)
			|| 
			((i1 < qe) && (others[i1].cost < v[i0].cost))) {
			p1 = &others[i1];
			i1++;
		}
		else {
			p1 = &v[i0];
			i0++;
		}
		PUSHNODE();
	}
	while (i1 < qe - 1) {
		nod *p0 = &others[i1];
		nod *p1 = &others[i1 + 1];
		PUSHNODE();
		i1 += 2;
	}
	for (int i = 0; i < N; ++i)
		setRepr(i);
	LL ans = 0;
	for (int i = 0; i < N; ++i)
		ans += v[i].cost * repr[i].first;
	printf("%lld\n", ans);
	for (int i = 0; i < N; ++i)
		printf("%d %lld\n", repr[i].first, repr[i].second);
	return 0;
}