Cod sursa(job #1538639)

Utilizator sulzandreiandrei sulzandrei Data 29 noiembrie 2015 16:00:49
Problema Coduri Huffman Scor 65
Compilator cpp Status done
Runda Arhiva educationala Marime 3.04 kb
#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=0;i<pos;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;
}