Pagini recente » Cod sursa (job #733869) | Cod sursa (job #922331) | Cod sursa (job #1953886) | Cod sursa (job #1708170) | Cod sursa (job #1979577)
#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 MAXN 1000010
struct nod {
LL cost;
nod *parent;
int bit;
} v[MAXN], others[MAXN << 1];
int N;
pair<int, int> 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;
}
int 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));
scanf("%d", &N);
for (int i = 0; i < N; ++i)
scanf("%lld", &v[i].cost);
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 %d\n", repr[i].first, repr[i].second);
return 0;
}