Pagini recente » Cod sursa (job #1442589) | Cod sursa (job #320751) | Cod sursa (job #2694079) | Cod sursa (job #2405898) | Cod sursa (job #3233665)
#include <bits/stdc++.h>
using namespace std;
ifstream in("huffman.in");
ofstream out("huffman.out");
using ll = long long;
const int lim = 2e6+4;
const ll inf = 4e18;
queue<int> frunze;
queue<int> artificiale;
ll freq[lim];
int lefty[lim];
int righty[lim];
int deep[lim];
int ans[lim];
int n, cnt;
void df(int nod) {
if(nod <= n) {
return ;
}
deep[lefty[nod]] = deep[righty[nod]] = deep[nod] + 1;
ans[lefty[nod]] = ans[righty[nod]] = ans[nod];
ans[righty[nod]] |= (1LL<<deep[nod]);
df(lefty[nod]);
df(righty[nod]);
}
int main() {
in>>n;
for(int i=1;i<=n;++i) {
in>>freq[i];
frunze.push(i);
}
cnt = n;
for(int iter=n;iter>=2;--iter) {
int n[2];
for(int i=0;i<2;++i) {
ll lmin = inf, rmin = inf;
if(!frunze.empty()) {
lmin = freq[frunze.front()];
}
if(!artificiale.empty()) {
rmin = freq[artificiale.front()];
}
if(lmin<=rmin) {
n[i] = frunze.front();
frunze.pop();
} else {
n[i] = artificiale.front();
artificiale.pop();
}
}
++cnt;
freq[cnt] = freq[n[0]] + freq[n[1]];
artificiale.push(cnt);
lefty[cnt] = n[0];
righty[cnt] = n[1];
}
df(cnt);
ll sum = 0;
for(int i=1;i<=n;++i) {
sum += freq[i]*deep[i];
}
out<<sum<<'\n';
for(int i=1;i<=n;++i) {
out<<deep[i]<<' '<<((1LL<<deep[i])-1)^ans[i]<<'\n';
}
return 0;
}