Cod sursa(job #2792257)

Utilizator OrzaSERBANSerban Orza OrzaSERBAN Data 1 noiembrie 2021 12:14:25
Problema Coduri Huffman Scor 70
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.9 kb
#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;
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;
    m=n;
    // 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 esye ca un arbore si pentru ca atunci cand cream un element mai adunam
        //inca o data ce aveam deja sub el si asa se obtine tot level*val
    }
}
void codeaza01(int poz,long long cod,int level)
{
    v[poz].val=cod;
    v[poz].level=level;
    if(poz>0)
    {
        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;

    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';
    }

}