Pagini recente » Cod sursa (job #1498514) | Cod sursa (job #2018632) | Cod sursa (job #667592) | Cod sursa (job #948840) | Cod sursa (job #972644)
Cod sursa(job #972644)
#include <fstream>
#include <queue>
#include <cstdio>
#define In "huffman.in"
#define Out "huffman.out"
#define min(a,b) ((a)<(b)?(a):(b))
#define LL long long
#define PLLN pair < LL , node* >
#define PLI pair < LL , int >
#define Nmax 1000010
#define Lim 500000
#define Next (++pos==Lim)?(f.read(Buffer,Lim),pos = 0):0
using namespace std;
struct node
{
node *l, *r;
int ind;
node()
{
ind = 0;
l = r = NULL;
}
};
PLI sol[Nmax];
node *Root = new node;
queue< PLLN >Q[2];
int N, pos;
LL Sum;
char Buffer[Lim];
ifstream f(In);
inline void Read(int &x)
{
while(Buffer[pos]<'0' || '9'<Buffer[pos])
Next;
x = 0;
while('0'<=Buffer[pos] && Buffer[pos]<='9')
{
x = x*10 +Buffer[pos]-'0';
Next;
}
}
inline void Read()
{
int x;
node *A;
Read(N);
for(int i = 1;i <= N ; ++i)
{
Read(x);
A = new node;
A->ind = i;
Q[0].push(make_pair(x,A));
}
f.close();
}
inline PLLN Min()
{
PLLN A;
A.first = 0;
if(Q[0].empty())
{
if(Q[1].empty())
return A;
A = Q[1].front();
Q[1].pop();
return A;
}
if(Q[1].empty())
{
A = Q[0].front();
Q[0].pop();
return A;
}
if(Q[0].front()<Q[1].front())
{
A = Q[0].front();
Q[0].pop();
}
else
{
A = Q[1].front();
Q[1].pop();
}
return A;
}
inline void BuildTree()
{
PLLN X, Y;
node *A,*Last;
while(true)
{
X = Min();
Y = Min();
if(X.first<=0 || Y.first<=0)
{
Root = Last;
return;
}
A = new node;
A->l = X.second;
A->r = Y.second;
Sum += X.first+Y.first;
Last = A;
Q[1].push(make_pair(X.first+Y.first,A));
}
}
inline void BuildSol(node *_node,const LL X, const int length)
{
if(_node->ind)
{
sol[_node->ind].first = X;
sol[_node->ind].second = length;
return;
}
if(_node->l)
BuildSol(_node->l,(X<<1),length+1);
if(_node->r)
BuildSol(_node->r,(X<<1)+1,length+1);
}
inline void Write()
{
freopen(Out,"w",stdout);
printf("%lld\n",Sum);
for(int i = 1;i <= N; ++i)
printf("%d %lld\n",sol[i].second,sol[i].first);
}
int main()
{
Read();
BuildTree();
BuildSol(Root,0,0);
Write();
return 0;
}