Pagini recente » Cod sursa (job #205813) | Cod sursa (job #3174664) | Cod sursa (job #1611920) | Cod sursa (job #255849) | Cod sursa (job #2792275)
#include <bits/stdc++.h>
using namespace std;
ifstream f("huffman.in");//huffman
ofstream g("huffman.out");
int n,m;
long long suma;
struct nod
{
int level,dr;
int st;
long long val;
};//v[2000001];
struct nodLight
{
int i;
long long val;
};
int nheap;
vector<nodLight> vv;
vector<nod> v;
void up(int k)
{
while(k>1 and vv[k].val<vv[k/2].val)
{
swap(vv[k],vv[k/2]);
k=k/2;
}
}
void down(int nn,int k)
{
bool ok=true;
int j,kk;
while(ok)
{
ok=false;
j=k;
kk=2*k;
if(kk<=nn)
{
j=kk;
if(kk+1<=nn)
{
if(vv[kk].val>vv[kk+1].val)
j=kk+1;
}
if(vv[k].val>vv[j].val)
{
swap(vv[k],vv[j]);
k=j;
ok=true;
}
}
}
}
void Add(long long val)
{
nodLight nodNou;
nheap++;
nodNou.i=n;
nodNou.val=val;
vv.push_back(nodNou);
// vv[nheap].i=n;
// vv[nheap].val=val;
up(nheap);
}
void Remove(int k)
{
vv[k]=vv[nheap];
vv.erase(vv.begin()+nheap);// adica el de pe poz nheap+1 in vv adica vv[nheap]
nheap--;
// if(k==1)
// down(nheap,k);
//else
if(vv[k].val<vv[k/2].val)
up(k);
else
down(nheap,k);
}
void createArbore()
{
//luam cele mai mici 2 noduri dupa val
int i,ii;
// in v avem toate nodurile(nu sunt sortate)
//in vv avem mereu in vv[1] nodul cu vv.val minim
//cream legaturi intre nodurile din v (arborele)
for(ii=1;ii<m;ii++)
{
//cream un nod nou
n++;
v[n].val=vv[1].val;
v[n].st=vv[1].i;
Remove(1);
v[n].val+=vv[1].val;
v[n].dr=vv[1].i;
Remove(1);
Add(v[n].val);
suma=suma+v[n].val;
//am putea calcula suma si in codeaza01 adunand
// v[i].level*v[i].val daca i face parte din elementele initiale
//dar vv este ca un arbore si pentru ca atunci cand cream un element mai adunam
//inca o data ce aveam deja sub el, asa se obtine tot level*val
}
}
void codeaza01(int poz,long long cod,int level)
{
v[poz].val=cod;
v[poz].level=level;
if(v[poz].st)
{
level++;
cod=(cod<<1);
codeaza01(v[poz].st,cod,level);
cod++;
codeaza01(v[poz].dr,cod,level);
}
}
int main()
{
int i,j,z,k;
f>>n;
v.resize(2*n+1);
vv.resize(n+1);
// cout<<sizeof(v)<<" "<<sizeof(vv)<<'\n';
// return 0;
nheap=n;
m=n;
for(i=1;i<=n;i++)
{
f>>v[i].val;
vv[i].i=i;
vv[i].val=v[i].val;
}
createArbore();
codeaza01(n,0,0);
//cout<<" "<<sizeof(vv);
g<<suma<<'\n';
for(i=1;i<=m;i++)
{
g<<v[i].level<<" "<<v[i].val<<'\n';
}
return 0;
}