Pagini recente » Cod sursa (job #1265489) | Cod sursa (job #1830667) | Cod sursa (job #1732530) | Cod sursa (job #305319) | Cod sursa (job #374138)
Cod sursa(job #374138)
#include<stdio.h>
#define infile "huffman.in"
#define outfile "huffman.out"
#define nmax (1000*1001)
#define bmax 63
struct nod
{
long long val; //valoarea din acest nod
int lg; //lungimea de la radacina pana la el
int t; //tatal nodului
char b; //tipul bitului (adica daca e de dreapta sau de stanga "=))'" )
int st,dr; //adresa catre cei 2 fii
} n[2*nmax]; //informatiile arborelui ce se formeaza
long long b[bmax]; //b[i]=2^i
int m; //numarul de noduri
int rad; //radacina arborelui
long long lg; //lungimea noului text
inline void unit(int i, int j, int k)
{ //uneste nodurile i si j in nodul k
n[k].val=n[i].val+n[j].val;
n[k].st=i; n[k].dr=j;
}
inline int min(int *st1, int dr1, int *st2, int dr2)
{ //valoarea minima dintre cele doua cozi
if(*st1<=dr1 && (*st2>dr2 || n[*st1].val<=n[*st2].val)) { *st1+=1; return *st1-1; }
*st2+=1; return *st2-1;
}
long long numar(int x)
{ //numarul ce-l formeaza aceasta frunza
long long nr=0;
int h;
for(h=0;x;x=n[x].t,h++)
if(n[x].b)
nr+=b[h];
return nr;
}
void read()
{
int i;
scanf("%d\n",&m);
for(i=1;i<=m;i++)
scanf("%lld\n",&n[i].val);
}
void init()
{
int st1=3,dr1=m; //capetele primei cozi
int st2=m+1,dr2=m+1; //capetele celeilalte cozi
int i;
//initializam coada 2
unit(1,2,st2);
//transformam padurea intr-un arbore huffman
while(st1<=dr1 || st2<dr2)
unit(min(&st1,dr1,&st2,dr2),min(&st1,dr1,&st2,dr2),dr2+1),dr2++;
//salvam radacina arborelui
rad=dr2;
//construim vectorul b
for(b[0]=i=1;i<bmax;i++)
b[i]=2*b[i-1];
}
void dfs(int rad, int lg)
{
n[rad].lg=lg;
if(n[rad].st) n[n[rad].st].t=rad,dfs(n[rad].st,lg+1);
if(n[rad].dr) n[n[rad].dr].t=rad,n[n[rad].dr].b=1,dfs(n[rad].dr,lg+1);
}
void solve()
{
int i;
//calculam lungimea totala a textului
for(i=1;i<=m;i++)
lg+=n[i].val*n[i].lg;
}
void write()
{
int i;
//lungimea noului text
printf("%lld\n",lg);
//afisem informatiile fiecarui caracter
for(i=1;i<=m;i++)
printf("%d %lld\n",n[i].lg,numar(i));
}
int main()
{
freopen(infile,"r",stdin);
freopen(outfile,"w",stdout);
read();
init();
dfs(rad,0);
solve();
write();
fclose(stdin);
fclose(stdout);
return 0;
}