Pagini recente » Cod sursa (job #1927704) | Cod sursa (job #59826) | Cod sursa (job #187681) | Cod sursa (job #477581) | Cod sursa (job #3236853)
#pragma GCC optimize("O3,unroll-loops")
#pragma GCC target("avx2,bmi,bmi2,lzcnt,popcnt")
#include <bits/stdc++.h>
using namespace std;
class parser{
private:
FILE *input_file;
static const int SIZE = 1 << 12;
int cursor;
char buffer[SIZE];
inline void advance(){
++cursor;
if(cursor == SIZE){
cursor = 0;
fread(buffer, SIZE, 1, input_file);
}
}
public:
parser() {};
parser(const char *file_name){
input_file = fopen(file_name, "r");
cursor = 0;
fread(buffer, SIZE, 1, input_file);
}
inline parser &operator >>(int &n){
while(!isdigit(buffer[cursor])) advance();
n = 0;
while(isdigit(buffer[cursor])){
n = n * 10 + buffer[cursor] - 48;
advance();
}
return *this;
}
};
parser fin("huffman.in");
ofstream fout("huffman.out");
int v[1000005];
int t[2000005];
bool viz[2000005];
int nrb[2000005];
long long r[2000005];
deque < pair <int, long long> > q;
int main()
{
int n,i,x;
long long rez = 0;
fin >> n;
for(i = 1; i <= n; i++) fin >> v[i];
if(n == 1){
fout << v[1] << "\n";
fout << "1 0";
return 0;
}
int k = 1,e = n;
t[k] = t[k + 1] = ++e;
q.push_back({e, v[k] + v[k + 1]});
k += 2;
while(k <= n){
long long s1 = 1e9, s2 = v[k] + q.front().second, s3 = 1e9;
if(k != n) s1 = v[k] + v[k + 1];
if(q.size() >= 2) s3 = q[1].second + q[0].second;
if(s1 <= min(s2, s3)){
t[k] = t[k + 1] = ++e;
q.push_back({e, v[k] + v[k + 1]});
k += 2;
}
else if(s2 <= min(s1, s3)){
t[k] = t[q.front().first] = ++e;
q.push_back({e, v[k] + q.front().second});
q.pop_front();
k++;
}
else{
t[q[0].first] = t[q[1].first] = ++e;
q.push_back({e, q[0].second + q[1].second});
q.pop_front();
q.pop_front();
}
}
while(q.size() > 1){
t[q[0].first] = t[q[1].first] = ++e;
q.push_back({e, q[0].second + q[1].second});
q.pop_front();
q.pop_front();
}
for(i = e - 1; i > 0; i--){
if(!viz[t[i]]){
r[i] = (r[t[i]] << 1LL);
nrb[i] = nrb[t[i]] + 1;
viz[t[i]] = 1;
}
else{
r[i] = (r[t[i]] << 1LL) + 1;
nrb[i] = nrb[t[i]] + 1;
}
if(i <= n) rez += 1LL * (nrb[i] * v[i]);
}
// for(i = 1; i < e; i++) fout << i << " " << t[i] << "\n";
fout << rez << "\n";
for(i = 1; i <= n; i++) fout << nrb[i] << " " << r[i] << "\n";
return 0;
}