Cod sursa(job #826525)

Utilizator tzipleatudTudor Tiplea tzipleatud Data 30 noiembrie 2012 20:43:02
Problema Coduri Huffman Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2.08 kb
#include <fstream>
#include <cassert>
#include <cstdio>
#define NM 2000010

using namespace std;

FILE* fin=fopen("huffman.in","r");
FILE* fout=fopen("huffman.out","w");
const int maxb=8192;
char buf[maxb];
int ptr=0;

inline int GetInt()
{
    int nr=0;
    while(buf[ptr]<'0'||'9'<buf[ptr])
        if (++ptr>=maxb) fread(buf,maxb,1,fin),ptr=0;
    while ('0'<=buf[ptr]&&buf[ptr]<='9')
    {
        nr=nr*10+buf[ptr]-'0';
        if (++ptr>=maxb) fread(buf,maxb,1,fin),ptr=0;
    }
    return nr;
}

struct NodeType
{
    int Sons[2];
    long long V;
};

NodeType Node[NM];
int N,K;
int i,j;
int Length[NM];
int Front[2],Back[2];
int Q[2][NM];
long long Val[NM];
long long ANS;
int son,cson;

void DF (int CNode, int Level, long long Code)
{
    if (Node[CNode].Sons[0]==0 || Node[CNode].Sons[1]==0)
    {
        Length[CNode]=Level;
        Val[CNode]=Code;

        return;
    }

    DF(Node[CNode].Sons[0], Level+1, 2LL*Code);
    DF(Node[CNode].Sons[1], Level+1, 2LL*Code+1);
}

int main ()
{
    N=GetInt();

    Front[0]=Front[1]=1;
    Back[0]=N;
    K=N;

    for (i=1; i<=N; i++)
    {
        Node[i].V=GetInt();
        Q[0][i]=i;
    }

    long long CVAL;
    int P;

    while (Front[0]+Front[1]<=Back[0]+Back[1])
    {
        ++K;

        for (son=0; son<2; son++)
        {
            CVAL=-1;
            P=0;

            for (cson=0; cson<2; cson++)
                if ((Node[Q[cson][Front[cson]]].V<CVAL || CVAL==-1) && Front[cson]<=Back[cson])
                {
                    CVAL=Node[Q[cson][Front[cson]]].V;
                    P=cson;
                }

            assert(Front[P]>=0 && Front[P]<NM);

            Node[K].Sons[son]=Q[P][Front[P]];
            Node[K].V+=Node[Q[P][Front[P]]].V;
            Front[P]++;
        }

        ANS+=Node[K].V;
        Q[1][++Back[1]]=K;
    }

    DF(K,0,0);

    fprintf(fout,"%lld\n",ANS);

    for (i=1; i<=N; i++)
        fprintf(fout,"%d %lld\n",Length[i],Val[i]);

    fclose(fin);
    fclose(fout);

    return 0;
}