Pagini recente » Cod sursa (job #961318) | Cod sursa (job #2593390) | Cod sursa (job #2483392) | Cod sursa (job #2237589) | Cod sursa (job #1535124)
#include <iostream>
#include <fstream>
#include <string>
#include <bitset>
using namespace std;
ifstream in("huffman.in");
ofstream out("huffman.out");
bitset<1000003> bs;
struct node
{
long long freq;
node *left,*right;
int value;
};
struct number
{
unsigned long long nr;
int length;
string s;
};
node* H[1000003];
number numbers[1000003];
char s[1000003];
int pos = -1;
long long sum = 0;
inline int ls(int i)
{
return (2*i);
}
inline int rs(int i)
{
return (2*i+1);
}
inline int father(int i)
{
return (i/2);
}
void Heapify(int,int);
void BuildHeap(int n)
{
for(int i = n/2; i>0 ; i-- )
Heapify(i,n);
}
node * pop(int n)
{
swap(H[1],H[n]);
n--;
Heapify(1,n);
return H[n+1];
}
void push(node * nod ,int n)
{
n++;
H[n] = nod;
int pos = n;
while(pos!=1 && H[pos]->freq < H[father(pos)]->freq)
{
swap(H[pos],H[father(pos)]);
pos = father(pos);
}
}
void Heapify(int i,int n)
{
int posmin,pos = i;
while(1)
{
posmin = pos;
if ( ls(pos) <= n && H[ls(pos)]->freq<H[posmin]->freq )
posmin = ls(pos);
if ( rs(pos)<= n && H[rs(pos)]->freq<H[posmin]->freq)
posmin = rs(pos);
if ( pos!=posmin )
{
swap(H[pos],H[posmin]);
pos = posmin;
}
else
break;
}
}
void go(node * nod)
{
pos++;
if (nod->left!= NULL)
{
bs[pos] =0;
s[pos] ='0';
go(nod->left);
}
if( nod->right!=NULL)
{
s[pos] = '1';
bs[pos] = 1;
go(nod->right);
}
if(nod->left == NULL && nod->right == NULL)
{
numbers[nod->value].length =pos;
unsigned long long nrb2=0;
for(int i=pos-1;i>=0;i--)
nrb2=nrb2*2+bs[i];
numbers[nod->value].nr =nrb2;
s[pos+1] = '\0';
numbers[nod->value].s = s;
}
else
sum += nod->freq;
bs[pos] = 0;
s[pos] = '\0';
pos--;
}
int main()
{
int n;
in >> n;
for(int i = 1 ; i <= n ; i ++)
{
H[i] = new node;
H[i]->left = NULL;
H[i]->right = NULL;
}
for(int i = 1 ; i <= n ; i++)
{
in>>H[i]->freq;
H[i]->value = i;
}
int mysize = n;
BuildHeap(mysize);
while (mysize> 1)
{
node *father = new node;
node *left = pop(mysize);
mysize--;
node *right = pop(mysize);
mysize--;
if(left->freq!=right->freq)
{
father->left = left;
father->right = right;
}
else
{
father->left = right;
father->right = left;
}
father->freq = left->freq+right->freq;
push(father,mysize);
mysize++;
}
node *root = H[1];
go(root);
out<<sum<<'\n';
for(int i = 1 ; i <= n ; i ++)
out<<numbers[i].length<<" "<<numbers[i].nr<<'\n';
return 0;
}