Cod sursa(job #1958778)

Utilizator razvandRazvan Dumitru razvand Data 8 aprilie 2017 19:08:09
Problema Coduri Huffman Scor 80
Compilator cpp Status done
Runda Arhiva educationala Marime 2.21 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");

int read() {
    if(P == SZ) {
        in >> buf;
        P = 0;
    }
    while(!isdigit(buf[P]))
        P++;
    int rez = 0;
    while(isdigit(buf[P]))
        rez = rez*10 + buf[P++] - '0';
    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() {

    in >> n;
    //n = read();
    se = n;
    p2 = se+1;
    int x;

    for(int i = 1; i <= n; i++) {
        in >> x;
        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;
}