Cod sursa(job #3301184)

Utilizator MihaiZ777MihaiZ MihaiZ777 Data 22 iunie 2025 18:49:43
Problema Coduri Huffman Scor 70
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.85 kb
#include <algorithm>
#include <cmath>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <vector>
#include <fstream>
#include <cstring>
using namespace std;

#define fast_io ios::sync_with_stdio(0); cin.tie(0); do{}while(0)
typedef long long ll;

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

const int MAXN = 1e6 + 5;

int n;
long long frv[MAXN * 2];
queue<int> realKeys;
queue<int> virtualKeys;
int lf[MAXN], rg[MAXN];
pair<int, long long> ans[MAXN];
int id = 0;
long long sum = 0;

void ReadData() {
	fin >> n;
	for (int i = 0; i < n; i++) {
		fin >> frv[i];
		realKeys.push(id++);
	}
}

int ExtractMinKey() {
	int entry;
	if (virtualKeys.empty()) {
		entry = realKeys.front();
		realKeys.pop();
	} else if (realKeys.empty()) {
		entry = virtualKeys.front();
		virtualKeys.pop();
	} else if (frv[realKeys.front()] < frv[virtualKeys.front()]) {
		entry = realKeys.front();
		realKeys.pop();
	} else {
		entry = virtualKeys.front();
		virtualKeys.pop();
	}
	return entry;
}

int BuildHuffman() {
	while (realKeys.size() + virtualKeys.size() > 1) {
		int a = ExtractMinKey();
		int b = ExtractMinKey();

		lf[id] = a;
		rg[id] = b;
		frv[id] = frv[a] + frv[b];
		virtualKeys.push(id);
		id++;
	}
	return virtualKeys.front();
}

void BuildAnswer(long long node, long long height, long long value) {
	if (node < n) {
		ans[node] = {height, value};
		sum += height * frv[node];
		return;
	}
	BuildAnswer(lf[node], height + 1, value << 1);
	BuildAnswer(rg[node], height + 1, (value << 1) | 1);
}

void Solve() {
	long long root = BuildHuffman();
	BuildAnswer(lf[root], 1, 0);
	BuildAnswer(rg[root], 1, 1);

	fout << sum << '\n';
	for (int i = 0; i < n; i++) {
		fout << ans[i].first << ' ' << ans[i].second << '\n';
	}
}

int main() {
	ReadData();
	Solve();
	return 0;
}