Cod sursa(job #885485)

Utilizator howsiweiHow Si Wei howsiwei Data 22 februarie 2013 05:58:04
Problema Coduri Huffman Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.34 kb
#include <iostream>
#include <fstream>
#include <algorithm>
#include <vector>
#include <deque>
using namespace std;
typedef unsigned long long ull;

struct node {
	node() { data=-1; freq=1<<30; }
	int child[2];
	ull freq;
	int data;
};
vector<node> a;
vector<ull> code;

void hufftree() {
	int n=a.size();
	int fr1=0, fr2=n;
	for (int j=1; j<n; ++j) {
		a.push_back(node());
		for (int i=0; i<2; ++i) {
			if (fr1==n ||  a[fr2].freq < a[fr1].freq) {
				a.back().child[i]=fr2++;
			}
			else {
				a.back().child[i]=fr1++;
			}
		}
		a.back().freq = a[a.back().child[0]].freq + a[a.back().child[1]].freq;
	}
}

void store(node & tmp, ull num, ull & len) {
	len+=tmp.freq;
	if (tmp.data!=-1) {
		code[tmp.data]=num;
		return;
	}
	store(a[tmp.child[0]], num<<1, len);
	store(a[tmp.child[1]], (num<<1)+1, len);
}

int main() {
	freopen("huffman.in","r",stdin);
	freopen("huffman.out","w",stdout);
	//ifstream fin("huffman.in");
	//ofstream fout("huffman.out");
	int n; scanf("%d",&n);
	a.reserve(2*n-1);
	a.resize(n);
	for (int i=0; i<n; ++i) {
		a[i].data=i;
		scanf("%lld",&a[i].freq);
	}
	hufftree();
	code.resize(n);
	ull len=0;
	store(a.back(), 1ull, len);
	printf("%lld\n",len-a.back().freq);
	//fout << len-a.back().freq << '\n';
	for (int i=0; i<n; ++i) {
		unsigned int tmp=63-__builtin_clzll(code[i]);
		printf("%u %lld \n", tmp, (code[i]^(1ull<<tmp)));
	}
	return 0;
}