Pagini recente » Cod sursa (job #3031293) | Cod sursa (job #2467978) | Cod sursa (job #24164) | Cod sursa (job #467141) | Cod sursa (job #1452195)
#include <fstream>
#include <cstdio>
using namespace std;
ifstream f("huffman.in");
int N;
const long long INF = 1000000000000000001;
struct Node{
long long val;
int sons[2];} Array[3000005];
int R[5000005];
int ind,ind2;
int Length[1000005];
long long Code[1000005],node;
long long res=0;
void Read()
{
f>>N;
node=N;
for(int i=1;i<=N;i++)
f>>Array[i].val;
}
void DFS(int node,int level,long long code)
{
for(int i=0;i<=1;i++)
if(Array[node].sons[i]!=0)
DFS(Array[node].sons[i],level+1,code*2+i);
if(Array[node].sons[0]!=0)
return;
Length[node]=level;
Code[node]=code;
}
void Solve()
{
int Begin1=1,Begin2=1,counter=0;
while(Begin1<=N || (ind==0 || Begin2<=ind))
{
long long x,y,z,t;
if(Begin1>N)
x=INF;
else
x=Array[Begin1].val;
if(Begin1==N)
y=INF;
else
y=Array[Begin1+1].val;
if(Begin2>ind)
z=INF;
else
z=Array[R[Begin2]].val;
if(Begin2>=ind)
t=INF;
else
t=Array[R[Begin2+1]].val;
long long minim=min(min(x+y,x+z),z+t);
if(minim>INF && min(min(min(x,y),z),t)<INF)
{
break;
}
if(minim>INF && min(min(min(x,y),z),t)>INF)
break;
if(z+t==minim)
{
R[++ind]=++node;
Array[node].val=minim;
Array[node].sons[0]=R[Begin2];
Array[node].sons[1]=R[Begin2+1];
Begin2+=2;
continue;
}
if(x+z==minim)
{
R[++ind]=++node;
Array[node].sons[0]=Begin1;
Array[node].sons[1]=R[Begin2];
Array[node].val=minim;
Begin1++;
Begin2++;
continue;
}
if(x+y==minim)
{
R[++ind]=++node;
Array[node].sons[0]=Begin1;
Array[node].sons[1]=Begin1+1;
Array[node].val=minim;
Begin1+=2;
continue;
}
}
while(Array[node].sons[0]==0)
--node;
DFS(node,0,0);
}
int main()
{
freopen("huffman.out","w",stdout);
Read();
Solve();
for(int i=1;i<=N;i++)
res+=Array[i].val*(long long)Length[i];
printf("%lld\n",res);
for(int i=1;i<=N;i++)
printf("%d %lld\n",Length[i],Code[i]);
return 0;
}