Cod sursa(job #3039221)

Utilizator vladth11Vlad Haivas vladth11 Data 28 martie 2023 12:17:45
Problema Coduri Huffman Scor 0
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.21 kb
#include <bits/stdc++.h>
#define debug(x) cerr << #x << " " << x << "\n"
#define debugs(x) cerr << #x << " " << x << " "
#pragma GCC optimize("Ofast")

using namespace std;
typedef long long ll;
typedef pair <int, int> pii;

const ll NMAX = 1000001;
const ll INF = (1LL << 60);
const ll nrbits = 17;
const ll MOD = 998244353;

short cc[NMAX * 2];
pii g[NMAX * 2][2];
ll sum;

pair <ll, int> operator + ( pair <ll, int> a,  pair <ll, int> b) {
    return {a.first + b.first, a.second + b.second};
}

void minSelf( pair <ll, int> &a,  pair <ll, int> b) {
    a = min(a, b);
}

ll f[NMAX * 2];
pair <int, ll> sol[NMAX];

void addEdge(int a, int b, int c) {
    g[a][++cc[a]] = {b, c};
}

void DFS(int node, int lvl, ll nr) {
    if(cc[node] == 0) {
        sum += (ll)f[node] * lvl;
        sol[node] = {lvl, nr};
    }
    for(int i = 1; i <= cc[node]; i++){
        pair <ll, int> x = g[node][i];
        DFS(x.first, lvl + 1, nr * 2 + x.second);
    }
}


queue <int> v;
queue <int> q;

pair <ll, int> getmin() {
    pair <ll, int> minim = {INF, 0};
    if(v.size()) {
        minSelf(minim, {f[v.front()], v.front()});
    }
    if(q.size()) {
        minSelf(minim, {f[q.front()], q.front()});
    }
    return minim;
}

int main() {
//#ifdef HOME
    ifstream cin("huffman.in");
    ofstream cout("huffman.out");
//#endif // HOME
    int n, i, ini = 0;
    cin >> n;
    for(i = 1; i <= n; i++) {
        cin >> f[i];
        v.push(i);
    }
    ini = n;
    while(v.size() + q.size() > 1) {
        pair <ll, int> minim = {INF, 0};
        n++;
        pair <ll, int> x = getmin();
        if(v.size() && x.second == v.front()) {
            v.pop();
        } else {
            q.pop();
        }
        pair <ll, int> y = getmin();
        if(v.size() && y.second == v.front())
            v.pop();
        else
            q.pop();
        addEdge(n, y.second, 1);
        addEdge(n, x.second, 0);
        minim = (x + y);
        f[n] = minim.first;
        q.push(n);
    }
    /// Caz special pt n == 1
    DFS(n, 0, 0);
    cout << sum << "\n";
    for(i = 1; i <= ini; i++) {
        cout << sol[i].first << " " << sol[i].second << "\n";
    }
}