Cod sursa(job #1231153)

Utilizator Ionut228Ionut Calofir Ionut228 Data 19 septembrie 2014 18:57:54
Problema Coduri Huffman Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.61 kb
#include <cstdio>
#include <queue>

using namespace std;

int N;
int Q[2][2000002], nodnow;
long long lgnow, bsnow, result;
long long val[2000002], lg[2000002], bs[2000002];
int V[2000002][2];
int pbeg[2], pend[2];

void Dfs(int nodnow)
{
    if (nodnow <= N)
    {
        lg[nodnow] = lgnow;
        bs[nodnow] = bsnow;
        return;
    }

    ++lgnow;
    bsnow = bsnow * 2;
    Dfs(V[nodnow][0]);
    bsnow = bsnow + 1;
    Dfs(V[nodnow][1]);
    bsnow = bsnow / 2;
    --lgnow;
}

void solve()
{
    nodnow = N;

    while (pend[0] - pbeg[0] + pend[1] - pbeg[1] >= 0)
    {
        ++nodnow;
        for (int i = 0; i < 2; ++i)
        {
            int now = -1, wh;
            for (int j = 0; j < 2; ++j)
                if (pbeg[j] <= pend[j] && (now == -1 || val[Q[j][pbeg[j]]] < val[now]))
                {
                    now = Q[j][pbeg[j]];
                    wh = j;
                }

            ++pbeg[wh];
            val[nodnow] += val[now];
            V[nodnow][i] = now;
        }
        Q[1][++pend[1]] = nodnow;
    }

    Dfs(nodnow);
}

int main()
{
    freopen("huffman.in", "r", stdin);
    freopen("huffman.out", "w", stdout);

    scanf("%d", &N);
    for (int i = 1; i <= N; ++i)
    {
        scanf("%lld", &val[i]);
        Q[0][i] = i;
    }

    pbeg[0] = 1;
    pend[0] = N;
    pbeg[1] = 1;
    pend[1] = 0;

    solve();

    for (int i = 1; i <= N; ++i)
        result += val[i] * lg[i];
    printf("%lld\n", result);
    for (int i = 1; i <= N; ++i)
        printf("%lld %lld\n", lg[i], bs[i]);

    return 0;
}