Pagini recente » Istoria paginii utilizator/raullt | Monitorul de evaluare | Istoria paginii utilizator/youtube1 | Monitorul de evaluare | Cod sursa (job #996964)
Cod sursa(job #996964)
#include <iostream>
#include <fstream>
#define lim 1000000
#define Next ++pos == lim?f.read(buffer, lim), pos = 0:0
#define NMax 1000010
#define INF 4000000000000000000LL
using namespace std;
ifstream f ("huffman.in");
int pos;
char buffer[lim];
int n;
struct Nod
{
long long frecv;
int fiu[2];
};
Nod a[2*NMax];
int q[2][NMax], pr[2], ul[2];
int lg[NMax];
long long sol, b[NMax];
inline void Read( int &x )
{
for (; buffer[pos] < '0' || buffer[pos] > '9'; Next);
for (x = 0; buffer[pos] >= '0' && buffer[pos] <= '9'; x = x*10 + (buffer[pos] - '0'), Next);
}
inline void Read()
{
Read(n);
int i, x;
for (i=1; i<=n; ++i)
{
Read(x);
a[i].frecv = x;
q[0][++ul[0]] = i;
}
f.close();
}
inline void DFS(int nod, long long numar, int nivel)
{
if (a[nod].fiu[0])
{
DFS(a[nod].fiu[0], numar<<1, nivel+1);
DFS(a[nod].fiu[1], (numar<<1)+1, nivel+1);
return ;
}
if (nod <= n)
{
lg[nod] = nivel;
b[nod] = numar;
}
}
inline void Solve()
{
int i, j, k, poz;
long long minim;
k = n;
pr[0] = pr[1] = 1;
while (pr[0] + pr[1] <= ul[0] + ul[1])
{
++k;
for (i = 0; i<2; ++i) /// pentru fiul stang si apoi cel drept
{
minim = INF;
for (j = 0; j<2; ++j) /// extrag minimul din cele 2 cozi
{
if (pr[j] <= ul[j] && a[q[j][pr[j]]].frecv < minim)
{
poz = j;
minim = a[q[j][pr[j]]].frecv;
}
}
a[k].fiu[i] = q[poz][pr[poz]];
a[k].frecv += minim;
++pr[poz];
}
sol += a[k].frecv;
q[1][++ul[1]] = k;
}
DFS(k, 0, 0);
}
inline void Write()
{
ofstream g("huffman.out");
g<<sol<<"\n";
int i;
for (i=1; i<=n; ++i)
g<<lg[i]<<" "<<b[i]<<"\n";
g.close();
}
int main()
{
Read();
Solve();
Write();
return 0;
}