Cod sursa(job #2074535)

Utilizator LucianTLucian Trepteanu LucianT Data 24 noiembrie 2017 18:50:05
Problema Coduri Huffman Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 3.66 kb
#include <bits/stdc++.h>
using namespace std;
const int maxN=1e6+5;
const long long INF=(1LL<<60);

struct nod{
    long long val;
    int sons[2];
}v[2*maxN];

class inParser
{
public:
    inParser(){};

    inParser(const char *file_name)
    {
        input_file=fopen(file_name,"r");
        cursor=0;
        fread(buffer,SIZE,1,input_file);
    }

    inline inParser &operator >>(long long &n)
    {
        while(buffer[cursor]<'0' || buffer[cursor]>'9')
            advance();

        n=0;
        while('0'<=buffer[cursor] && buffer[cursor]<='9'){
            n=n*10+buffer[cursor]-'0';
            advance();
        }

        return *this;
    }
private:
    FILE *input_file;
    static const int SIZE=1<<15;
    int cursor;
    char buffer[SIZE];

    inline void advance()
    {
        cursor++;
        if(cursor==SIZE){
            cursor=0;
            fread(buffer,SIZE,1,input_file);
        }
    }
};

class OutParser {
private:
    FILE *fout;
    char *buff;
    int sp;

    void write_ch(char ch) {
        if (sp == 50000) {
            fwrite(buff, 1, 50000, fout);
            sp = 0;
            buff[sp++] = ch;
        } else {
            buff[sp++] = ch;
        }
    }


public:
    OutParser(const char* name) {
        fout = fopen(name, "w");
        buff = new char[50000]();
        sp = 0;
    }
    ~OutParser() {
        fwrite(buff, 1, sp, fout);
        fclose(fout);
    }

    OutParser& operator << (int vu32) {
        if (vu32 <= 9) {
            write_ch(vu32 + '0');
        } else {
            (*this) << (vu32 / 10);
            write_ch(vu32 % 10 + '0');
        }
        return *this;
    }

    OutParser& operator << (long long vu64) {
        if (vu64 <= 9) {
            write_ch(vu64 + '0');
        } else {
            (*this) << (vu64 / 10);
            write_ch(vu64 % 10 + '0');
        }
        return *this;
    }

    OutParser& operator << (char ch) {
        write_ch(ch);
        return *this;
    }
    OutParser& operator << (const char *ch) {
        while (*ch) {
            write_ch(*ch);
            ++ch;
        }
        return *this;
    }
};

long long n;

int st[2],dr[2];
long long sol;
long long Que[2][maxN];
long long len[maxN],codes[maxN];

void dfs(int nod,long long cod,int dep)
{
    if(v[nod].sons[0]!=0){
        dfs(v[nod].sons[0],(cod<<1),dep+1);
        dfs(v[nod].sons[1],(cod<<1)|1,dep+1);
    }

    if(nod<=n){
        len[nod]=dep;
        codes[nod]=1LL*cod;
        //cerr<<codes[nod]<<" ";
    }
}

int main()
{
    inParser f("huffman.in");
    OutParser g("huffman.out");

    f>>n;
    for(int i=1;i<=n;i++)
        f>>v[i].val;

    int curr=n;
    for(int i=1;i<=n;i++)
        Que[0][i]=i;

    st[0]=st[1]=1;
    dr[0]=n;
    long long minn=INF;
    int which_que=0;

    while(st[0]+st[1] <= dr[0]+dr[1])
    {
        curr++;
        for(int i=0;i<2;i++){
            which_que=0;
            minn=INF;

            if(st[0]<=dr[0] && v[Que[0][st[0]]].val<minn){
                minn=v[Que[0][st[0]]].val;
                which_que=0;
            }
            if(st[1]<=dr[1] && v[Que[1][st[1]]].val<minn){
                minn=v[Que[1][st[1]]].val;
                which_que=1;
            }

            v[curr].sons[i]=Que[which_que][st[which_que]];
            v[curr].val+=v[Que[which_que][st[which_que]]].val;

            st[which_que]++;
        }
        sol+=v[curr].val;
        Que[1][++dr[1]]=curr;
    }

    dfs(curr,0,0);
    g<<sol<<"\n";

    for(int i=1;i<=n;i++)
        g<<len[i]<<" "<<codes[i]<<"\n";

    return 0;
}