Cod sursa(job #2910622)

Utilizator NToniBoSSNicolae Tonitza NToniBoSS Data 22 iunie 2022 20:15:06
Problema Coduri Huffman Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 3.64 kb
#include <bits/stdc++.h>
#define LIM 1<<17
#define EXT_NODES 1000000
/// TONI BO$$ was here
/// #MLC

using namespace std;
char BUF[LIM];
int poz;

inline char getChar(){
    poz++;
    if(poz>=LIM){
    	fread(BUF,LIM,1,stdin);
    	poz=0;
    }
    return BUF[poz];
}

inline int getNr(){
    int r=0, semn=1;
    char ch=getChar();
    while(isdigit(ch)==0 && ch!='-') ch=getChar();
    if(ch=='-'){
        semn=-1;
        ch=getChar();
    }
    while(isdigit(ch)!=0){
        r=r*10+semn*(ch-'0');
        ch=getChar();
    }
    return r;
}

struct huffman
{
    long long freq;
    int leftChild;
    int rightChild;
}v[EXT_NODES + 1], q[EXT_NODES + 1];

pair <int, long long> rez[EXT_NODES + 1];

long long sum;

void dfs(int node, int lev, long long code)
{
    if(node > EXT_NODES)
    {
        sum += q[node - EXT_NODES].freq;
        dfs(q[node - EXT_NODES].leftChild, lev + 1, code << 1LL);
        dfs(q[node - EXT_NODES].rightChild, lev + 1, 1 + code << 1LL);
    }
    else
    {
        rez[node] = {lev, code};
    }
    return ;
}

int main()
{
    int n, f, p, i, j;
    freopen("huffman.in","r",stdin);
    freopen("huffman.out","w",stdout);
    poz = LIM;
    n = getNr();
    for(i = 1; i <= n; i++)
    {
        f = getNr();
        v[i].freq = f;
        v[i].leftChild = v[i].rightChild = 0;
    }
    p = 1;
    i = 1;
    j = 0;
    while(true)
    {
        if(p > n && i == j)
            break;
        if(i > j)
        {
            q[++j] = {v[p].freq + v[p + 1].freq, p, p + 1};
            p += 2;
        }
        else
            if(i == j)
                if(q[i].freq <= v[p + 1].freq)
                {
                    q[++j] = {v[p].freq + q[i].freq, p, i + EXT_NODES};
                    p++;
                    i++;
                }
                else
                {
                    q[++j] = {v[p].freq + v[p + 1].freq, p, p + 1};
                    p += 2;
                }
            else
                if(p == n)
                    if(v[p].freq <= q[i + 1].freq)
                    {
                        q[++j] = {v[p].freq + q[i].freq, p, i + EXT_NODES};
                        p++;
                        i++;
                    }
                    else
                    {
                        q[++j] = {q[i].freq + q[i + 1].freq, i + EXT_NODES, i + 1 + EXT_NODES};
                        i += 2;
                    }
                else
                    if(p > n)
                    {
                        q[++j] = {q[i].freq + q[i + 1].freq, i + EXT_NODES, i + 1 + EXT_NODES};
                        i += 2;
                    }
                    else
                        if(v[p].freq > q[i + 1].freq)
                        {
                            q[++j] = {q[i].freq + q[i + 1].freq, i + EXT_NODES, i + 1 + EXT_NODES};
                            i += 2;
                        }
                        else
                            if(q[i].freq > v[p + 1].freq)
                            {
                                q[++j] = {v[p].freq + v[p + 1].freq, p, p + 1};
                                p += 2;
                            }
                            else
                            {
                                q[++j] = {v[p].freq + q[i].freq, p, i + EXT_NODES};
                                p++;
                                i++;
                            }
    }
    dfs(j + EXT_NODES, 0, 0);
    printf("%lld\n", sum);
    for(i = 1; i <= n; i++)
        printf("%d %lld\n", rez[i].first, rez[i].second);

    return 0;
}