Cod sursa(job #1958786)

Utilizator razvandRazvan Dumitru razvand Data 8 aprilie 2017 19:13:13
Problema Coduri Huffman Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2.35 kb
#include <iostream>
#include <queue>
#include <fstream>
#include <climits>

using namespace std;

pair<int, int> kids[2*1000003];
long long cod[1000003];
int ap[2*1000003];
int n;
int freq[1000003];
int p1=1,p2=1;
int se;
int tim = 0;
const int SZ = 1000000;
char buf[SZ+3];
int P=SZ;
ifstream in("huffman.in");
ofstream out("huffman.out");

char nextch() {
    if(P == SZ) {
        in.read(buf,SZ);
        P = 0;
    }
    return buf[P++];
}

int read() {
    char ch = nextch();
    while(!isdigit(ch))
        ch = nextch();
    int rez = 0;
    while(isdigit(ch)) {
        rez = rez*10 + ch - '0';
        ch = nextch();
    }
    //cout << "TEST " << rez << '\n';
    return rez;
}

void take2() {

    long long val1 = LLONG_MAX/2;
    long long val2 = LLONG_MAX/2;
    long long val3 = LLONG_MAX/2;

    if(p1+1 <= n)
        val1 = ap[p1]+ap[p1+1];
    if(p2+1 <= se)
        val2 = ap[p2]+ap[p2+1];
    if(p1 <= n && p2 <= se)
        val3 = ap[p1]+ap[p2];

    if(val1 <= val2 && val1 <= val3) {
        ap[++se] = val1;
        kids[se].first = p1;
        kids[se].second = p1+1;
        p1 += 2;
        return;
    }

    if(val2 <= val1 && val2 <= val3) {
        ap[++se] = val2;
        kids[se].first = p2;
        kids[se].second = p2+1;
        p2 += 2;
        return;
    }

    ap[++se] = val3;
    kids[se].first = p1;
    kids[se].second = p2;
    p1++;
    p2++;

}

void rec(int nod, long long crr, int am) {

    if(nod > n) {
        //cout << nod << " " << kids[nod].first << " " << kids[nod].second << " " << crr << " " << am << " " << crr + (1<<am) << '\n';
        rec(kids[nod].first, crr*2, am+1);
        rec(kids[nod].second, crr*2+1, am+1);
    } else {
        freq[nod] = am;
        cod[nod] = crr;
    }

}

int main() {

    n = read();
    //cout << n << '\n';
    se = n;
    p2 = se+1;
    int x;

    for(int i = 1; i <= n; i++) {
        x = read();
        ap[i] = x;
    }

    int tim = n;
    long long newC = 0;

    for(int i = 1; i < n; i++) {
        ++tim;
        take2();
    }
    rec(2*n-1, 0, 0);
    long long tot = 0;

    for(int i = 1; i <= n; i++)
        tot += 1LL*freq[i]*ap[i];

    out << tot << '\n';

    for(int i = 1; i <= n; i++) {
        out << freq[i] << " " << cod[i] << '\n';
    }

    return 0;
}