Cod sursa(job #1878986)

Utilizator zdavid112zIon David-Gabriel zdavid112z Data 14 februarie 2017 17:25:19
Problema Coduri Huffman Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2.28 kb
#include <cstdio>
#define maxn 1000000
#define inf 0x3f3f3f3f
#define infl (1LL * inf * inf)

using namespace std;
typedef long long llong;

struct Heap
{
    int st, dr;
    llong val;
} h[maxn * 2 + 1];

int q[2][maxn], st[2], dr, lh;
int v[maxn];
llong rez[maxn];
llong sum = 0;
int lrez[maxn];
int n;

void query(int nod, int nivel, llong cod)
{
    if(h[nod].dr == -1)
    {
        lrez[h[nod].st] = nivel;
        rez[h[nod].st] = cod;
        return;
    }
    sum += h[nod].val;
    query(h[nod].st, nivel + 1, cod * 2);
    query(h[nod].dr, nivel + 1, cod * 2 + 1);
}

int main()
{
    int i;
    freopen("huffman.in", "r", stdin);
    freopen("huffman.out", "w", stdout);
    scanf("%d", &n);
    for(i = 0; i < n; i++)
    {
        scanf("%lld", &h[i].val);
        q[0][i] = i;
        h[i].st = i;
        h[i].dr = -1;
    }
    lh = n;
    st[0] = 0;
    st[1] = 0;
    dr = 0;
    for(i = 1; i < n; i++)
    {
        int caz = 0;
        llong m1 = infl;
        if(st[0] < n - 1)
        {
            m1 = h[q[0][st[0]]].val + h[q[0][st[0] + 1]].val;
            caz = 1;
        }
        if(st[0] < n && st[1] < dr)
        {
            if(m1 > h[q[0][st[0]]].val + h[q[1][st[1]]].val)
            {
                m1 = h[q[0][st[0]]].val + h[q[1][st[1]]].val;
                caz = 2;
            }
        }
        if(st[1] < dr - 1)
        {
            if(m1 > h[q[1][st[1]]].val + h[q[1][st[1] + 1]].val)
            {
                m1 = h[q[1][st[1]]].val + h[q[1][st[1] + 1]].val;
                caz = 3;
            }
        }

        h[lh].val = m1;
        if(caz == 1)
        {
            h[lh].st = q[0][st[0]];
            h[lh].dr = q[0][st[0] + 1];
            st[0] += 2;
        }
        else if(caz == 2)
        {
            h[lh].st = q[0][st[0]];
            h[lh].dr = q[1][st[1]];
            st[0]++;
            st[1]++;
        }
        else
        {
            h[lh].st = q[1][st[1]];
            h[lh].dr = q[1][st[1] + 1];
            st[1] += 2;
        }
        q[1][dr++] = lh;
        lh++;
    }
    query(lh - 1, 0, 0);
    printf("%lld\n", sum);
    for(i = 0; i < n; i++)
    {
        printf("%d %lld\n", lrez[i], rez[i]);
    }
    return 0;
}