Pagini recente » Cod sursa (job #303144) | Cod sursa (job #2203235) | Cod sursa (job #2388272) | Cod sursa (job #400688) | Cod sursa (job #1478349)
#include <bits/stdc++.h>
using namespace std;
struct hufm{
long long ap;
int sons[2];
};
const int nofSimbols = (int)2 * 1e6 + 5;
const long long nofAp = (int) 1e18;
long long n;
hufm simb[nofSimbols];
long long tLen;
long long lg[nofSimbols], rep[nofSimbols];
queue < pair <long long, int > > que[2];
char ax[nofSimbols >> 8];
int pz;
#define dim 19
inline void cit(long long &x) {
x = 0;
while (ax[pz] < '0' || ax[pz] > '9')
if (++pz == dim)
fread(ax, 1, dim, stdin), pz = 0;
while (ax[pz] >= '0' && ax[pz] <= '9') {
x = x * 10 + ax[pz] - '0';
if (++pz == dim)
fread(ax, 1, dim, stdin), pz = 0;
}
}
void read(){
freopen ("huffman.in", "r", stdin);
cit(n);
for (int i = 1; i <= n; ++i){
long long now;
cit(now);
simb[i].ap = now;
que[0].push({now, i});
}
}
void makeTree(){
int kNod = n;
while (que[0].size() + que[1].size() > 1){
++kNod;
for (int son = 0; son < 2; ++son){
bool from = 0;
long long now = -1;
if (que[0].size())
now = que[0].front().first;
if (que[1].size() and (que[1].front().first < now or now == -1) )
now = que[1].front().first, from = 1;
simb[kNod].sons[son] = que[from].front().second;
simb[kNod].ap += que[from].front().first;
que[from].pop();
}
que[1].push({simb[kNod].ap, kNod});
}
}
inline void dfs (int pos, long long code, int level){
if (simb[pos].sons[0]){
dfs(simb[pos].sons[0], code << 1LL, level + 1);
dfs(simb[pos].sons[1], (code << 1LL) | 1LL, level + 1);
return;
}
lg[pos] = level;
rep[pos] = code;
tLen += simb[pos].ap * level;
}
void solve(){
freopen ("huffman.out", "w", stdout);
dfs(2 * n - 1, 0, 0);
printf ("%lld\n", tLen);
for (int i = 1; i <= n; ++i)
printf ("%lld %lld\n", lg[i], rep[i]);
}
int main(){
read();
makeTree();
solve();
}