static void generate_len_table(uint8_t *dst, uint64_t *stats, int size){

    heap_elem_t h[size];

    int up[2*size];

    int len[2*size];

    int offset, i, next;



    for(offset=1; ; offset<<=1){

        for(i=0; i<size; i++){

            h[i].name = i;

            h[i].val = (stats[i] << 8) + offset;

        }

        for(i=size/2-1; i>=0; i--)

            heap_sift(h, i, size);



        for(next=size; next<size*2-1; next++){

            // merge the two smallest entries, and put it back in the heap

            uint64_t min1v = h[0].val;

            up[h[0].name] = next;

            h[0].val = INT64_MAX;

            heap_sift(h, 0, size);

            up[h[0].name] = next;

            h[0].name = next;

            h[0].val += min1v;

            heap_sift(h, 0, size);

        }



        len[2*size-2] = 0;

        for(i=2*size-3; i>=size; i--)

            len[i] = len[up[i]] + 1;

        for(i=0; i<size; i++) {

            dst[i] = len[up[i]] + 1;

            if(dst[i] > 32) break;

        }

        if(i==size) break;

    }

}

static void generate_len_table(uint8_t *dst, uint64_t *stats, int size){

    heap_elem_t h[size];

    int up[2*size];

    int len[2*size];

    int offset, i, next;



    for(offset=1; ; offset<<=1){

        for(i=0; i<size; i++){

            h[i].name = i;

            h[i].val = (stats[i] << 8) + offset;

        }

        for(i=size/2-1; i>=0; i--)

            heap_sift(h, i, size);



        for(next=size; next<size*2-1; next++){

            

            uint64_t min1v = h[0].val;

            up[h[0].name] = next;

            h[0].val = INT64_MAX;

            heap_sift(h, 0, size);

            up[h[0].name] = next;

            h[0].name = next;

            h[0].val += min1v;

            heap_sift(h, 0, size);

        }



        len[2*size-2] = 0;

        for(i=2*size-3; i>=size; i--)

            len[i] = len[up[i]] + 1;

        for(i=0; i<size; i++) {

            dst[i] = len[up[i]] + 1;

            if(dst[i] > 32) break;

        }

        if(i==size) break;

    }

}

static void FUNC_0(uint8_t *VAR_0, uint64_t *VAR_1, int VAR_2){

    heap_elem_t h[VAR_2];

    int VAR_3[2*VAR_2];

    int VAR_4[2*VAR_2];

    int VAR_5, VAR_6, VAR_7;



    for(VAR_5=1; ; VAR_5<<=1){

        for(VAR_6=0; VAR_6<VAR_2; VAR_6++){

            h[VAR_6].name = VAR_6;

            h[VAR_6].val = (VAR_1[VAR_6] << 8) + VAR_5;

        }

        for(VAR_6=VAR_2/2-1; VAR_6>=0; VAR_6--)

            heap_sift(h, VAR_6, VAR_2);



        for(VAR_7=VAR_2; VAR_7<VAR_2*2-1; VAR_7++){

            

            uint64_t min1v = h[0].val;

            VAR_3[h[0].name] = VAR_7;

            h[0].val = INT64_MAX;

            heap_sift(h, 0, VAR_2);

            VAR_3[h[0].name] = VAR_7;

            h[0].name = VAR_7;

            h[0].val += min1v;

            heap_sift(h, 0, VAR_2);

        }



        VAR_4[2*VAR_2-2] = 0;

        for(VAR_6=2*VAR_2-3; VAR_6>=VAR_2; VAR_6--)

            VAR_4[VAR_6] = VAR_4[VAR_3[VAR_6]] + 1;

        for(VAR_6=0; VAR_6<VAR_2; VAR_6++) {

            VAR_0[VAR_6] = VAR_4[VAR_3[VAR_6]] + 1;

            if(VAR_0[VAR_6] > 32) break;

        }

        if(VAR_6==VAR_2) break;

    }

}

static void FUNC_0(uint8_t *VAR_0, uint64_t *VAR_1, int VAR_2){ heap_elem_t h[VAR_2]; int VAR_3[2*VAR_2]; int VAR_4[2*VAR_2]; int VAR_5, VAR_6, VAR_7; for(VAR_5=1; ; VAR_5<<=1){ for(VAR_6=0; VAR_6<VAR_2; VAR_6++){ h[VAR_6].name = VAR_6; h[VAR_6].val = (VAR_1[VAR_6] << 8) + VAR_5; } for(VAR_6=VAR_2/2-1; VAR_6>=0; VAR_6--) heap_sift(h, VAR_6, VAR_2); for(VAR_7=VAR_2; VAR_7<VAR_2*2-1; VAR_7++){ uint64_t min1v = h[0].val; VAR_3[h[0].name] = VAR_7; h[0].val = INT64_MAX; heap_sift(h, 0, VAR_2); VAR_3[h[0].name] = VAR_7; h[0].name = VAR_7; h[0].val += min1v; heap_sift(h, 0, VAR_2); } VAR_4[2*VAR_2-2] = 0; for(VAR_6=2*VAR_2-3; VAR_6>=VAR_2; VAR_6--) VAR_4[VAR_6] = VAR_4[VAR_3[VAR_6]] + 1; for(VAR_6=0; VAR_6<VAR_2; VAR_6++) { VAR_0[VAR_6] = VAR_4[VAR_3[VAR_6]] + 1; if(VAR_0[VAR_6] > 32) break; } if(VAR_6==VAR_2) break; } }