Pagini recente » Cod sursa (job #2964171) | Cod sursa (job #2142880) | Cod sursa (job #176441) | Cod sursa (job #1352887) | Cod sursa (job #2927589)
/**
* 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';
ll frq[2 * mxN + 2], cod[2 * mxN + 2];
int L[2 * mxN + 2], R[2 * mxN + 2], len[2 * mxN + 2];
queue<int> Q1, Q2;
void init() {
memset(L, -1, sizeof(L));
memset(R, -1, sizeof(R));
}
ll getNext() {
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) {
F0R(i, n) {
Q1.emplace(i);
}
int node = n - 1;
while (sz(Q1) + sz(Q2) > 1) {
int node0 = getNext();
int node1 = getNext();
node++;
frq[node] = frq[node0] + frq[node1];
L[node] = node0;
R[node] = node1;
Q2.emplace(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);
ifstream fin("huffman.in");
ofstream fout("huffman.out");
int n;
fin >> n;
init(n);
F0R(i, n) fin >> frq[i];
int root = build(n);
dfs(root, 0, 0);
fout << tot_sum << nl;
F0R(i, n) {
fout << len[i] << ' ' << cod[i] << nl;
}
return 0;
}