Pagini recente » Cod sursa (job #709520) | Cod sursa (job #2507366) | Cod sursa (job #1993009) | Cod sursa (job #1566858) | Cod sursa (job #1979584)
#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;
}
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++;
}
others[qe].cost = p0->cost + p1->cost;
p0->parent = &others[qe]; p0->bit = 0;
p1->parent = &others[qe]; p0->bit = 1;
++qe;
}
while (i1 < qe - 1) {
nod *p0 = &others[i1];
nod *p1 = &others[i1 + 1];
others[qe].cost = p0->cost + p1->cost;
p0->parent = &others[qe]; p0->bit = 0;
p1->parent = &others[qe]; p0->bit = 1;
++qe;
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;
}