Cod sursa(job #983664)
#include <fstream>
#include <cstdio>
#include <queue>
using namespace std;
const int Nmax = 1000010;
#define val first
#define key second
typedef long long i64;
typedef pair<i64,int> Pair;
typedef struct
{
// i64 val;
int left,right;
} huff;
ofstream G("huffman.out");
int N,K;
int frf,grf,frs,grs;
pair<int,int> fr[Nmax];
Pair gr[Nmax];
huff H[Nmax<<1];
i64 Out;
int lun[Nmax];i64 code[Nmax];
void Get(int nod,i64 Key,int Depth)
{
// if ( H[nod].left || H[nod].right ) Out += H[nod].val;
if ( nod <= N )
{
lun[nod] = Depth;
code[nod] = Key;
return;
}
Get(H[nod].left,Key*2LL+0LL,Depth+1);
Get(H[nod].right,Key*2LL+1LL,Depth+1);
}
const int Buffer=1<<13;
char Buff[Buffer]; int Next=0;
#define F stdin
int get_int()
{
int Nbr=0;
while( Buff[Next]<'0' || '9'<Buff[Next] )
if ( ++Next >= Buffer ) fread(Buff,Buffer,1,F), Next=0;
while ( '0'<=Buff[Next] && Buff[Next]<='9' )
{
Nbr=Nbr*10+Buff[Next]-'0';
if ( ++Next >= Buffer ) fread(Buff,Buffer,1,F), Next=0;
}
return Nbr;
}
int main()
{
freopen("huffman.in","r",stdin);
N=get_int();
for (int i=1;i<=N;++i)
{
fr[++frs] = make_pair( get_int() , i );
// H[i].val = fr[frs].val;
H[i].right = H[i].left = 0;
}
K = N;
frf = grf = 1;
while ( (frs-frf+1) > 0 || (grs-grf+1) > 1 )
{
Pair p = make_pair( 0 , ++K );
if ( ( fr[frf].val <= gr[grf].val && (frs-frf+1) > 0 ) || ( (frs-frf+1) > 0 && (grs-grf+1) == 0 ) )
{
p.val += fr[frf].val;
H[p.key].left = fr[frf].key;
++frf;
}
else
{
p.val += gr[grf].val;
H[p.key].left = gr[grf].key;
++grf;
}
if ( ( fr[frf].val <= gr[grf].val && (frs-frf+1) > 0 ) || ( (frs-frf+1) > 0 && (grs-grf+1) == 0 ) )
{
p.val += fr[frf].val;
H[p.key].right = fr[frf].key;
++frf;
}
else
{
p.val += gr[grf].val;
H[p.key].right = gr[grf].key;
++grf;
}
if ( H[p.key].left > H[p.key].right )
swap( H[p.key].left , H[p.key].right );
// H[p.key].val = p.val;
gr[++grs] = p;
Out += p.val;
}
Get( K,0LL,0 );
G<<Out<<'\n';
for (int i=1;i<=N;++i)
G<<lun[i]<<' '<<code[i]<<'\n';
}