Cod sursa(job #996964)

Utilizator romircea2010FMI Trifan Mircea Mihai romircea2010 Data 12 septembrie 2013 22:54:21
Problema Coduri Huffman Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2.05 kb
#include <iostream>
#include <fstream>
#define lim 1000000
#define Next ++pos == lim?f.read(buffer, lim), pos = 0:0
#define NMax 1000010
#define INF 4000000000000000000LL

using namespace std;

ifstream f ("huffman.in");
int pos;
char buffer[lim];
int n;
struct Nod
{
    long long frecv;
    int fiu[2];
};
Nod a[2*NMax];
int q[2][NMax], pr[2], ul[2];
int lg[NMax];
long long sol, b[NMax];

inline void Read( int &x )
{
    for (; buffer[pos] < '0' || buffer[pos] > '9'; Next);
    for (x = 0; buffer[pos] >= '0' && buffer[pos] <= '9'; x = x*10 + (buffer[pos] - '0'), Next);
}

inline void Read()
{
    Read(n);
    int i, x;
    for (i=1; i<=n; ++i)
    {
        Read(x);
        a[i].frecv = x;
        q[0][++ul[0]] = i;
    }
    f.close();
}

inline void DFS(int nod, long long numar, int nivel)
{
    if (a[nod].fiu[0])
    {
        DFS(a[nod].fiu[0], numar<<1, nivel+1);
        DFS(a[nod].fiu[1], (numar<<1)+1, nivel+1);
        return ;
    }
    if (nod <= n)
    {
        lg[nod] = nivel;
        b[nod] = numar;
    }
}

inline void Solve()
{
    int i, j, k, poz;
    long long minim;
    k = n;
    pr[0] = pr[1] = 1;
    while (pr[0] + pr[1] <= ul[0] + ul[1])
    {
        ++k;
        for (i = 0; i<2; ++i) /// pentru fiul stang si apoi cel drept
        {
            minim = INF;
            for (j = 0; j<2; ++j) /// extrag minimul din cele 2 cozi
            {
                if (pr[j] <= ul[j] && a[q[j][pr[j]]].frecv < minim)
                {
                    poz = j;
                    minim = a[q[j][pr[j]]].frecv;
                }
            }
            a[k].fiu[i] = q[poz][pr[poz]];
            a[k].frecv += minim;
            ++pr[poz];
        }
        sol += a[k].frecv;
        q[1][++ul[1]] = k;
    }
    DFS(k, 0, 0);
}

inline void Write()
{
    ofstream g("huffman.out");
    g<<sol<<"\n";
    int i;
    for (i=1; i<=n; ++i)
        g<<lg[i]<<" "<<b[i]<<"\n";
    g.close();
}

int main()
{
    Read();
    Solve();
    Write();
    return 0;
}