Cod sursa(job #1087939)

Utilizator roby2001Sirius roby2001 Data 19 ianuarie 2014 23:31:24
Problema Coduri Huffman Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2.03 kb
/*
          ~Keep It Simple!~
*/

#include<stdio.h>

#define NMax 1000005
#define inf 1LL * 1000000000 * 1000000000
struct nod
{
	long long val;
	int left,right;
}node[2*NMax];


int N,SingleBegin,SingleEnd,MergeBegin,MergeEnd,Nr;
int FinalLg[NMax];
long long FinalVal[NMax],S,SingleQueue[NMax],MergeQueue[NMax];


void DF(int nod,int level,long long val)
{
	if( node[nod].left == NULL)
	{
		FinalLg[nod] = level;
		FinalVal[nod] = val;
	}
	else
	{
		DF(node[nod].left,level+1,val*2);
		DF(node[nod].right,level+1,val*2+1);
	}
}


void BuildTree()
{
	SingleBegin=1;
	SingleEnd=N;
	MergeBegin=MergeEnd=1;
	Nr = N;
	while( SingleBegin<SingleEnd || MergeBegin<MergeEnd)
	{
		int x=-1,y=-1;
		if( SingleBegin >= SingleEnd && MergeBegin == MergeEnd-1)
			break;
		if(MergeEnd <= MergeBegin || node[SingleQueue[SingleBegin]].val <= node[MergeQueue[MergeBegin]].val && SingleBegin <= SingleEnd)
			x = SingleQueue[SingleBegin++];
		else if ( SingleEnd <= SingleBegin || node[SingleQueue[SingleBegin]].val > node[MergeQueue[MergeBegin]].val && MergeBegin <= MergeEnd)
			x = MergeQueue[MergeBegin++];

		if(MergeEnd <= MergeBegin || node[SingleQueue[SingleBegin]].val <= node[MergeQueue[MergeBegin]].val && SingleBegin <= SingleEnd)
			y = SingleQueue[SingleBegin++];
		else if ( SingleEnd <= SingleBegin || node[SingleQueue[SingleBegin]].val > node[MergeQueue[MergeBegin]].val && MergeBegin <= MergeEnd)
			y = MergeQueue[MergeBegin++];
		
		if( x == -1 || y == -1)
			break;

		Nr++;

		node[Nr].val = node[x].val + node[y].val;
		node[Nr].left=x;
		node[Nr].right=y;

		S += node[Nr].val;
		MergeQueue[MergeEnd++] = Nr;
	}
}

int main()
{
	freopen("huffman.in","r",stdin);
	freopen("huffman.out","w",stdout);

	scanf("%d",&N);

	int x;

	for(int i=1; i<=N; i++)
	{
		scanf("%d",&node[i].val);
		SingleQueue[i] = i;
		MergeQueue[i] = inf;

	}

	BuildTree();

	DF(Nr,0,0);

	printf("%lld\n",S);

	for(int i=1; i<=N; i++)
		printf("%d %lld\n",FinalLg[i],FinalVal[i]);
    

	return 0;
}