Pagini recente » Cod sursa (job #2377649) | Cod sursa (job #1858316) | Cod sursa (job #826955) | Cod sursa (job #1168086) | Cod sursa (job #1211496)
#include <algorithm>
#include <cstdio>
#include <vector>
#include <queue>
using namespace std;
class FileInput {
public:
FileInput() {}
FileInput(const char *filename) {
file = fopen(filename, "r");
fread(buffer, BUFFER_SIZE, 1, file);
cursor = 0;
}
inline FileInput & operator >> (int &n) {
while(buffer[cursor] == ' ' || buffer[cursor] == '\n') {
advance();
}
n = 0;
while(isdigit(buffer[cursor])) {
n = n * 10 + buffer[cursor] - '0';
advance();
}
return *this;
}
private:
static const int BUFFER_SIZE = 1 << 19;
FILE* file;
char buffer[BUFFER_SIZE];
int cursor;
inline void advance() {
++ cursor;
if(cursor == BUFFER_SIZE) {
cursor = 0;
fread(buffer, BUFFER_SIZE, 1, file);
}
}
} fin("huffman.in");
class Huffman {
public:
Huffman(const int _Base = 0, const vector<int> &_Values = vector<int>()):
Base(_Base),
OriginalSize(_Values.size()),
Size(GetSize(Base, _Values.size())),
Cost(0LL),
G(vector< vector<int> > (Size, vector<int>()))
{
vector<long long> Q(Size, 0);
for (int i = 0; i < Size; i++)
Q[i] = i < OriginalSize ? _Values[i]: 0LL;
int left1 = 0, left2 = Size;
while (OriginalSize - left1 + Size - left2 >= Base)
{
G.push_back(vector<int>(Base));
long long value = 0;
for (int i = 0; i < Base; i++)
{
if (left1 < OriginalSize && (left2 >= Size || Q[left1] < Q[left2]))
{
value += Q[left1];
G.back()[i] = left1;
left1++;
}
else
{
value += Q[left2];
G.back()[i] = left2;
left2++;
}
}
Q.push_back(value);
Cost += value;
Size++;
}
}
vector< pair<int, long long> > getCoding() const {
queue< pair<int, pair<long long, int>> > Q;
Q.push(make_pair(Size - 1, make_pair(0, 0)));
vector< pair<int, long long> > ret(OriginalSize);
while (!Q.empty())
{
const int node = Q.front().first, level = Q.front().second.second;
const long long code = Q.front().second.first;
Q.pop();
int Psize = GetSize(Base, OriginalSize);
if (node < Psize)
{
if (node < OriginalSize)
ret[node] = make_pair(level, code);
continue;
}
for (int i = 0; i < Base; i++)
Q.push(make_pair(G[node][i], make_pair(code * Base + i, level + 1)));
}
return ret;
}
int size() const {
return OriginalSize;
}
int actual_size() const {
return Size;
}
long long cost() const {
return Cost;
}
private:
int Base;
int OriginalSize, Size;
long long Cost;
vector< vector<int> > G;
static int GetSize(const int Base, const int Size) {
return (Size - 3 + Base) / (Base - 1) * (Base - 1) + 1;
}
};
int main()
{
freopen("huffman.out", "w", stdout);
int N;
fin >> N;
vector<int> Values(N);
for (int i = 0; i < int(Values.size()); i++)
fin >> Values[i];
Huffman T = Huffman(2, Values);
printf("%lld\n", T.cost());
vector< pair<int, long long> > Codes = T.getCoding();
for (const auto p: Codes)
printf("%d %lld\n", p.first, p.second);
}