Pagini recente » Cod sursa (job #724303) | Cod sursa (job #2615028) | Cod sursa (job #2292750) | Cod sursa (job #3222563) | Cod sursa (job #2927582)
/**
* author: R0L3eX
* created: 20.10.2022 19:11:53
**/
#include "bits/stdc++.h"
#if defined(ONPC)
#include "bits/debug.h"
#endif
using namespace std;
using ll = long long;
using ld = long double;
using cd = complex<ld>;
using pi = pair<int, int>;
using pl = pair<ll, ll>;
using pd = pair<ld, ld>;
using vi = vector<int>;
using vd = vector<ld>;
using vl = vector<ll>;
using vpi = vector<pi>;
using vpl = vector<pl>;
using vcd = vector<cd>;
template<class T> using pq = priority_queue<T>;
template<class T> using pqg = priority_queue<T, vector<T>, greater<T>>;
#define FOR(i, a, b) for (int i=a; i<(b); i++)
#define F0R(i, a) for (int i=0; i<(a); i++)
#define FORd(i,a,b) for (int i = (b)-1; i >= a; i--)
#define F0Rd(i,a) for (int i = (a)-1; i >= 0; i--)
#define trav(a,x) for (auto& a : x)
#define uid(a, b) uniform_int_distribution<int>(a, b)(rng)
#define sz(x) (int)(x).size()
#define mp make_pair
#define pb push_back
#define fi first
#define se second
#define lb lower_bound
#define ub upper_bound
#define all(x) x.begin(), x.end()
#define rall(x) x.rbegin(), x.rend()
#define ins insert
template<class T> bool ckmin(T& a, const T& b) { return b < a ? a = b, 1 : 0; }
template<class T> bool ckmax(T& a, const T& b) { return a < b ? a = b, 1 : 0; }
mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
const int MOD = 1e9 + 7;
const int INF = 1e9;
const int mxN = 1e6;
const char nl = '\n';
vl frq, cod;
vi L, R, len;
void init(int n) {
frq = vl(2 * n + 2);
cod = vl(2 * n + 2);
len = vi(2 * n + 2);
L = vi(2 * n + 2, -1);
R = vi(2 * n + 2, -1);
}
ll getNext(queue<int> &Q1, queue<int> &Q2) {
int ans = 0;
if (Q1.empty()) {
ans = Q2.front();
Q2.pop();
} else if (Q2.empty()) {
ans = Q1.front();
Q1.pop();
} else if (frq[Q1.front()] < frq[Q2.front()]) {
ans = Q1.front();
Q1.pop();
} else {
ans = Q2.front();
Q2.pop();
}
return ans;
}
int build(int n) {
queue<int> Q1, Q2;
F0R(i, n) {
Q1.push(i);
}
int node = n - 1;
while (sz(Q1) + sz(Q2) > 1) {
int node0 = getNext(Q1, Q2);
int node1 = getNext(Q1, Q2);
node++;
frq[node] = frq[node0] + frq[node1];
L[node] = node0;
R[node] = node1;
Q2.push(node);
}
return Q2.front();
}
ll tot_sum = 0;
void dfs(int node, ll cur_cod, int cur_len) {
// if we are not in a leaf
if (L[node] != -1 && R[node] != -1) {
dfs(L[node], 2 * cur_cod, cur_len + 1);
dfs(R[node], 2 * cur_cod + 1, cur_len + 1);
} else {
cod[node] = cur_cod;
len[node] = cur_len;
tot_sum += frq[node] * len[node];
}
}
int main() {
// ios::sync_with_stdio(false);
// std::cin.tie(nullptr);
freopen("huffman.in", "r", stdin);
freopen("huffman.out", "w", stdout);
int n;
cin >> n;
init(n);
F0R(i, n) cin >> frq[i];
int root = build(n);
dfs(root, 0, 0);
cout << tot_sum << nl;
F0R(i, n) {
cout << len[i] << ' ' << cod[i] << nl;
}
return 0;
}