Pagini recente » Cod sursa (job #3017) | Cod sursa (job #2401406) | Profil katakuna | Cod sursa (job #1550050) | Cod sursa (job #2074535)
#include <bits/stdc++.h>
using namespace std;
const int maxN=1e6+5;
const long long INF=(1LL<<60);
struct nod{
long long val;
int sons[2];
}v[2*maxN];
class inParser
{
public:
inParser(){};
inParser(const char *file_name)
{
input_file=fopen(file_name,"r");
cursor=0;
fread(buffer,SIZE,1,input_file);
}
inline inParser &operator >>(long long &n)
{
while(buffer[cursor]<'0' || buffer[cursor]>'9')
advance();
n=0;
while('0'<=buffer[cursor] && buffer[cursor]<='9'){
n=n*10+buffer[cursor]-'0';
advance();
}
return *this;
}
private:
FILE *input_file;
static const int SIZE=1<<15;
int cursor;
char buffer[SIZE];
inline void advance()
{
cursor++;
if(cursor==SIZE){
cursor=0;
fread(buffer,SIZE,1,input_file);
}
}
};
class OutParser {
private:
FILE *fout;
char *buff;
int sp;
void write_ch(char ch) {
if (sp == 50000) {
fwrite(buff, 1, 50000, fout);
sp = 0;
buff[sp++] = ch;
} else {
buff[sp++] = ch;
}
}
public:
OutParser(const char* name) {
fout = fopen(name, "w");
buff = new char[50000]();
sp = 0;
}
~OutParser() {
fwrite(buff, 1, sp, fout);
fclose(fout);
}
OutParser& operator << (int vu32) {
if (vu32 <= 9) {
write_ch(vu32 + '0');
} else {
(*this) << (vu32 / 10);
write_ch(vu32 % 10 + '0');
}
return *this;
}
OutParser& operator << (long long vu64) {
if (vu64 <= 9) {
write_ch(vu64 + '0');
} else {
(*this) << (vu64 / 10);
write_ch(vu64 % 10 + '0');
}
return *this;
}
OutParser& operator << (char ch) {
write_ch(ch);
return *this;
}
OutParser& operator << (const char *ch) {
while (*ch) {
write_ch(*ch);
++ch;
}
return *this;
}
};
long long n;
int st[2],dr[2];
long long sol;
long long Que[2][maxN];
long long len[maxN],codes[maxN];
void dfs(int nod,long long cod,int dep)
{
if(v[nod].sons[0]!=0){
dfs(v[nod].sons[0],(cod<<1),dep+1);
dfs(v[nod].sons[1],(cod<<1)|1,dep+1);
}
if(nod<=n){
len[nod]=dep;
codes[nod]=1LL*cod;
//cerr<<codes[nod]<<" ";
}
}
int main()
{
inParser f("huffman.in");
OutParser g("huffman.out");
f>>n;
for(int i=1;i<=n;i++)
f>>v[i].val;
int curr=n;
for(int i=1;i<=n;i++)
Que[0][i]=i;
st[0]=st[1]=1;
dr[0]=n;
long long minn=INF;
int which_que=0;
while(st[0]+st[1] <= dr[0]+dr[1])
{
curr++;
for(int i=0;i<2;i++){
which_que=0;
minn=INF;
if(st[0]<=dr[0] && v[Que[0][st[0]]].val<minn){
minn=v[Que[0][st[0]]].val;
which_que=0;
}
if(st[1]<=dr[1] && v[Que[1][st[1]]].val<minn){
minn=v[Que[1][st[1]]].val;
which_que=1;
}
v[curr].sons[i]=Que[which_que][st[which_que]];
v[curr].val+=v[Que[which_que][st[which_que]]].val;
st[which_que]++;
}
sol+=v[curr].val;
Que[1][++dr[1]]=curr;
}
dfs(curr,0,0);
g<<sol<<"\n";
for(int i=1;i<=n;i++)
g<<len[i]<<" "<<codes[i]<<"\n";
return 0;
}