Pagini recente » Cod sursa (job #2302400) | Cod sursa (job #1440451) | Cod sursa (job #2189682) | Cod sursa (job #1715791) | Cod sursa (job #1958786)
#include <iostream>
#include <queue>
#include <fstream>
#include <climits>
using namespace std;
pair<int, int> kids[2*1000003];
long long cod[1000003];
int ap[2*1000003];
int n;
int freq[1000003];
int p1=1,p2=1;
int se;
int tim = 0;
const int SZ = 1000000;
char buf[SZ+3];
int P=SZ;
ifstream in("huffman.in");
ofstream out("huffman.out");
char nextch() {
if(P == SZ) {
in.read(buf,SZ);
P = 0;
}
return buf[P++];
}
int read() {
char ch = nextch();
while(!isdigit(ch))
ch = nextch();
int rez = 0;
while(isdigit(ch)) {
rez = rez*10 + ch - '0';
ch = nextch();
}
//cout << "TEST " << rez << '\n';
return rez;
}
void take2() {
long long val1 = LLONG_MAX/2;
long long val2 = LLONG_MAX/2;
long long val3 = LLONG_MAX/2;
if(p1+1 <= n)
val1 = ap[p1]+ap[p1+1];
if(p2+1 <= se)
val2 = ap[p2]+ap[p2+1];
if(p1 <= n && p2 <= se)
val3 = ap[p1]+ap[p2];
if(val1 <= val2 && val1 <= val3) {
ap[++se] = val1;
kids[se].first = p1;
kids[se].second = p1+1;
p1 += 2;
return;
}
if(val2 <= val1 && val2 <= val3) {
ap[++se] = val2;
kids[se].first = p2;
kids[se].second = p2+1;
p2 += 2;
return;
}
ap[++se] = val3;
kids[se].first = p1;
kids[se].second = p2;
p1++;
p2++;
}
void rec(int nod, long long crr, int am) {
if(nod > n) {
//cout << nod << " " << kids[nod].first << " " << kids[nod].second << " " << crr << " " << am << " " << crr + (1<<am) << '\n';
rec(kids[nod].first, crr*2, am+1);
rec(kids[nod].second, crr*2+1, am+1);
} else {
freq[nod] = am;
cod[nod] = crr;
}
}
int main() {
n = read();
//cout << n << '\n';
se = n;
p2 = se+1;
int x;
for(int i = 1; i <= n; i++) {
x = read();
ap[i] = x;
}
int tim = n;
long long newC = 0;
for(int i = 1; i < n; i++) {
++tim;
take2();
}
rec(2*n-1, 0, 0);
long long tot = 0;
for(int i = 1; i <= n; i++)
tot += 1LL*freq[i]*ap[i];
out << tot << '\n';
for(int i = 1; i <= n; i++) {
out << freq[i] << " " << cod[i] << '\n';
}
return 0;
}