Cod sursa(job #3304019)

Utilizator unomMirel Costel unom Data 19 iulie 2025 18:56:21
Problema Coduri Huffman Scor 80
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.08 kb
#include <fstream>
#include <vector>
#include <set>

using namespace std;

#define int long long

struct node
{
    signed st, dr;
    int sum;
};

ifstream in("huffman.in");
ofstream out("huffman.out");
int n, cnt, ans;
int st1, dr1;
int st2, dr2;
node v[2000005];
int frunze[1000015];
int interne[1000015];
pair<char, int> rez[1000005];
int INF = (1LL << 60);

void adauga(int a, int b)
{
    cnt++;
    v[cnt].st = a;
    v[cnt].dr = b;
    v[cnt].sum = v[a].sum + v[b].sum;

    dr2++;
    interne[dr2] = cnt;
}

void dfs(int node, int cod, int len)
{
    if(v[node].st == 0)
    {
        rez[node] = {len, cod};

        return;
    }

    ans += v[node].sum;

    dfs(v[node].st, 2 * cod, len + 1);
    dfs(v[node].dr, 2 * cod + 1, len + 1);
}

signed main()
{
    in>>n;

    for(int i = 1; i<=n + 5; i++)
    {
        frunze[i] = interne[i] = 0;
        //ca sa nu am treaba cu st sa treaca peste dr
        //(nu trece ca o sa fie costul mai mare si prefera mereu cealalta varianta)
    }

    v[0].sum = INF;

    int x;
    for(int i = 1; i<=n; i++)
    {
        in>>x;

        dr1++;
        frunze[dr1] = i;
        v[i].sum = x;
    }

    st1 = st2 = 1;

    cnt = n;
    for(int i = 1; i<n; i++)
    {
        int best = min(min(v[frunze[st1]].sum + v[frunze[st1 + 1]].sum, v[frunze[st1]].sum + v[interne[st2]].sum), v[interne[st2]].sum + v[interne[st2 + 1]].sum);

        //out<<best<<'\n';

        if(v[frunze[st1]].sum + v[frunze[st1 + 1]].sum == best)
        {
            adauga(frunze[st1], frunze[st1 + 1]);

            st1 += 2;
        }
        else if(v[frunze[st1]].sum + v[interne[st2]].sum == best)
        {
            adauga(frunze[st1], interne[st2]);

            st1++;
            st2++;
        }
        else
        {
            adauga(interne[st2], interne[st2 + 1]);

            st2 += 2;
        }
    }

    dfs(cnt, 0, 0);

    out<<ans<<'\n';
    for(int i = 1; i<=n; i++)
    {
        out<<(int)rez[i].first<<" "<<rez[i].second<<'\n';
    }

    return 0;
}