Pagini recente » Cod sursa (job #3254182) | Cod sursa (job #3261193)
#include<fstream>
#include<cstdio>
using namespace std;
const int NMAX=2e6+5,buffsize=(1<<16);
const long long p10=1e5,p10_2=p10*p10,p10_3=p10_2*p10,e10=5,e10_2=e10*2,e10_3=e10*3;
FILE* fn;
long long Size[NMAX];
int code[NMAX];
int p[NMAX];
short len[NMAX];
char buff[buffsize+20];
int bpos=buffsize;
int read(){
if(bpos==buffsize) fread(buff,1,buffsize,fn),bpos=0;
int n=0;
while(buff[bpos]>='0'){
n=(n<<1)+(n<<3)+(buff[bpos++]^48);
if(bpos==buffsize) fread(buff,1,buffsize,fn),bpos=0;
}
++bpos;
return n;
}
int cntdigits[p10+5];
int getdigits(long long n){
if(n<p10) return cntdigits[n];
if(n<p10_2) return e10+cntdigits[n/p10];
if(n<p10_3) return e10_2+cntdigits[n/p10_2];
return e10_3+cntdigits[n/p10_3];
}
void writell(long long n){
if(bpos>=buffsize) fwrite(buff,1,bpos,fn),bpos=0;
if(n==0){
buff[bpos++]='0';
return;
}
int ptr=(bpos+=getdigits(n));
while(n){
buff[--ptr]=(n%10)^48;
n/=10;
}
}
void writeshort(short n){
if(bpos>=buffsize) fwrite(buff,1,bpos,fn),bpos=0;
if(n>=10){
buff[bpos++]=(n/10)^48;
buff[bpos++]=(n%10)^48;
}
else buff[bpos++]=n^48;
}
int main()
{
for(int i=1;i<p10;i++) cntdigits[i]=cntdigits[i/10]+1;
fn=fopen("huffman.in","r");
int n=read();
int queue1l=0,queue1r=0,queue2l,queue2r;
while(queue1r<n){
Size[queue1r++]=read();
}
queue2l=queue2r=queue1r;
long long total_len=0;
for(int iter=0;iter<n-1;++iter){
int min1,min2;
if(queue2l!=queue2r && (queue1l==queue1r || Size[queue2l]<=Size[queue1l]))
min1=queue2l++;
else min1=queue1l++;
if(queue2l!=queue2r && (queue1l==queue1r || Size[queue2l]<=Size[queue1l]))
min2=queue2l++;
else min2=queue1l++;
code[min2]=1;
total_len+=(Size[queue2r]=Size[min1]+Size[min2]);
p[min1]=p[min2]=queue2r++;
}
for(int i=queue2l-1;i>=0;--i){
len[i]=len[p[i]]+1;
code[i]|=(code[p[i]]<<1);
}
fn=fopen("huffman.out","w");
bpos=0;
writell(total_len),buff[bpos++]='\n';
for(int i=0;i<n;++i){
writeshort(len[i]),buff[bpos++]=' ';
writell(code[i]),buff[bpos++]='\n';
}
fwrite(buff,1,buffsize,fn);
fclose(fn);
return 0;
}