Pagini recente » Cod sursa (job #753919) | Borderou de evaluare (job #1073821) | Cod sursa (job #3333880) | Cod sursa (job #1168420) | Cod sursa (job #3304022)
#include <fstream>
#include <vector>
using namespace std;
#define int long long
struct node
{
signed st, dr;
int sum;
};
ifstream in("huffman.in");
ofstream out("huffman.out");
int n, cnt, ans;
int st1, dr1;
int st2, dr2;
signed frec[1000005];
node v[1000005];
int frunze[1000015];
int interne[1000015];
pair<signed, int> rez[1000005];
int INF = (1LL << 60);
int functiesigma(int x)
{
if(x <= n)
{
return frec[x];
}
return v[x - n].sum;
}
void adauga(int a, int b)
{
cnt++;
v[cnt - n].st = a;
v[cnt - n].dr = b;
v[cnt - n].sum = functiesigma(a) + functiesigma(b);
dr2++;
interne[dr2] = cnt;
}
void dfs(signed node, int cod, signed len)
{
if(node <= n)
{
rez[node] = {len, cod};
return;
}
ans += v[node - n].sum;
dfs(v[node - n].st, 2 * cod, len + 1);
dfs(v[node - n].dr, 2 * cod + 1, len + 1);
}
signed main()
{
in>>n;
for(int i = 1; i<=n + 5; i++)
{
frunze[i] = interne[i] = 0;
//ca sa nu am treaba cu st sa treaca peste dr
//(nu trece ca o sa fie costul mai mare si prefera mereu cealalta varianta)
}
v[0].sum = INF;
for(int i = 1; i<=n; i++)
{
in>>frec[i];
dr1++;
frunze[dr1] = i;
}
st1 = st2 = 1;
cnt = n;
for(int i = 1; i<n; i++)
{
int best = min(min(functiesigma(frunze[st1]) + functiesigma(frunze[st1 + 1]), functiesigma(frunze[st1]) + functiesigma(interne[st2])), functiesigma(interne[st2]) + functiesigma(interne[st2 + 1]));
//out<<best<<'\n';
if(functiesigma(frunze[st1]) + functiesigma(frunze[st1 + 1]) == best)
{
adauga(frunze[st1], frunze[st1 + 1]);
st1 += 2;
}
else if(functiesigma(frunze[st1]) + functiesigma(interne[st2]) == best)
{
adauga(frunze[st1], interne[st2]);
st1++;
st2++;
}
else
{
adauga(interne[st2], interne[st2 + 1]);
st2 += 2;
}
}
dfs(cnt, 0, 0);
out<<ans<<'\n';
for(int i = 1; i<=n; i++)
{
out<<rez[i].first<<" "<<rez[i].second<<'\n';
}
return 0;
}