Pagini recente » Cod sursa (job #166111) | Cod sursa (job #3286336) | Cod sursa (job #334695) | Cod sursa (job #2245659) | Cod sursa (job #407541)
Cod sursa(job #407541)
// Catalin Balan
// Tue Mar 2 12:08:04 EET 2010
// Infoarena - Coduri Huffman - var cu heap ( n log n )
#include <cstdio>
#include <cstdlib>
#include <vector>
#include <algorithm>
#include <utility>
using namespace std;
#define NMAX 1000004
#define CHUNK 8192
#define FIN "huffman.in"
#define FOUT "huffman.out"
char g_buf[CHUNK];
int g_p=CHUNK-1;
inline long long get(FILE *f)
{
long long x = 0;
while (g_buf[g_p] < '0' || g_buf[g_p] > '9')
if (++g_p == CHUNK) fread(g_buf,1,CHUNK,f), g_p=0;
while (g_buf[g_p] >= '0' && g_buf[g_p] <= '9')
{
x = x*10 + g_buf[g_p]-'0';
if (++g_p == CHUNK) fread(g_buf,1,CHUNK,f), g_p=0;
}
return x;
}
struct node
{
long long val;
int fiu0, fiu1;
} noduri[ 2*NMAX ];
long long cod[NMAX], totlen;
int lung[NMAX];
//vector< pair< long long, int > > heap;
int n;
void df( int p, int depth, long long x )
{
//printf("%d - %lld %d %d\n", p, noduri[p].val, noduri[p].fiu0, noduri[p].fiu1);
if ( noduri[p].fiu0 )
{
df( noduri[p].fiu0, depth+1, x<<1 );
df( noduri[p].fiu1, depth+1, (x<<1)+1 );
return;
}
lung[p] = depth;
cod[p] = x;
totlen += depth * noduri[p].val;
}
void solve()
{
int i = n;
int q1 = 1, q2 = n+1, q;
long long aux;
// make_heap( heap.begin(), heap.end());
while ( q1 < n || q2 < i)
{
++i;
noduri[i].val = 0;
if ( q1 <= n && ( q2 >= i || noduri[q1].val <= noduri[q2].val ) ) {aux = noduri[q1].val; q = q1; q1++;}
else {aux = noduri[q2].val; q = q2; q2++;}
noduri[i].val += aux;
noduri[i].fiu0 = q;
if ( q1 <= n && ( q2 >= i || noduri[q1].val <= noduri[q2].val ) ) {aux = noduri[q1].val; q = q1; q1++;}
else {aux = noduri[q2].val; q = q2; q2++;}
noduri[i].val += aux;
noduri[i].fiu1 = q;
/* aux = heap.front();
noduri[i].val -= aux.first;
noduri[i].fiu0 = aux.second;
pop_heap( heap.begin(), heap.end() );
heap.pop_back();
aux = heap.front();
noduri[i].val -= aux.first;
noduri[i].fiu1 = aux.second;
pop_heap( heap.begin(), heap.end() );
heap.pop_back();
heap.push_back( make_pair( -noduri[i].val, i) );
*/
}
// aux = heap.front();
df( i, 0, 0 );
}
int main(int argv, char ** argc)
{
freopen(FIN, "r", stdin);
freopen(FOUT, "w", stdout);
n = get(stdin);
for (int i = 1; i <= n; ++i)
{
noduri[i].val = get(stdin);
noduri[i].fiu0 = noduri[i].fiu1 = 0;
// heap.push_back( make_pair( -noduri[i].val, i ) );
}
solve();
printf( "%lld\n", totlen );
for (int i = 1; i <= n; ++i)
{
printf( "%d %lld\n", lung[i], cod[i] );
}
return EXIT_SUCCESS;
}