Cod sursa(job #1095823)

Utilizator mihai995mihai995 mihai995 Data 31 ianuarie 2014 23:02:43
Problema Sortare prin comparare Scor 20
Compilator cpp Status done
Runda Arhiva educationala Marime 6.81 kb
#include <fstream>
#include <iostream>
#include <cstdlib>
using namespace std;

const int nil = 0x3f3f3f3f;

struct Per{
    int val, nr;

    void addOne(){
        nr++;
    }

    inline bool operator<(Per P){
        return val < P.val;
    }

    inline bool operator==(Per P){
        return val == P.val;
    }

    inline bool operator<=(Per P){
        return val <= P.val;
    }
};

template<class Data, const int cap, const int T>
class Btree{
    Data keyBuff[ (2 * T - 1) * cap / (T - 1) ];
    int sonBuff[ 2 * T * cap / (T - 1) ], size[ cap / (T - 1) ], freeStack[ 1 + cap / (T - 1) ], root, stepSize;

    inline Data* getKeyArray(int x){
        return keyBuff + (2 * T - 1) * x;
    }

    inline int* getSonArray(int x){
        return sonBuff + 2 * T * x;
    }

    inline bool isFull(int x){
        return 1 + size[x] == 2 * T;
    }

    inline bool isLeaf(int x){
        return sonBuff[2 * T * x] == nil;
    }

    int allocNode(){
        int nod = freeStack[ freeStack[0]-- ];
        *getSonArray(nod) = nil;
        size[nod] = 0;
        return nod;
    }

    void dealloc(int nod){
        freeStack[ ++freeStack[0] ] = nod;
    }

    int bSearch(Data* v, Data K, int N){
        int ans = 0;
        for (int step = stepSize, P = step ; step ; step >>= 1, P = ans ^ step)
            if ( P < N && v[P] <= K )
                ans = P;
        return ans;
    }

    void splitSon(int nod, int index){
        Data *key = getKeyArray(nod);
        int *son = getSonArray(nod);

        int st = son[index], dr = allocNode();
        Data *keySt = getKeyArray(st) + T, *keyDr = getKeyArray(dr);
        int *sonSt = getSonArray(st) + T, *sonDr = getSonArray(dr);

        for (int i = size[nod] ; i > index ; i--){
            key[i] = key[i - 1];
            son[i + 1] = son[i];
        }
        key[index] = keySt[-1];
        son[index + 1] = dr;
        size[nod]++;
        size[st] = T - 1;

        for (int i = 0 ; i < T - 1 ; i++)
            keyDr[i] = keySt[i];
        for (int i = 0 ; i < T ; i++)
            sonDr[i] = sonSt[i];
    }

    int browseTree(Data K, bool doSplits){
        if ( doSplits && isFull(root) ){
            int P = allocNode();
            *getSonArray(P) = root;
            root = P;
            splitSon(root, 0);
        }

        Data *key;
        int nod = root, index, *son;
        while (!isLeaf(nod)){
            key = getKeyArray(nod);
            son = getSonArray(nod);
            index = bSearch(key, K, size[nod]);
            if ( doSplits && isFull(son[index]) ){
                splitSon(nod, index);
                index++;
            }
            if (key[index] == K)
                return nod;
            nod = son[index];
        }
        return nod;
    }

    Data findMin(int nod, bool deleteIt){
        while (!isLeaf(nod))
            nod = *getSonArray(nod);
        if (deleteIt){
            Data *key = getKeyArray(nod);
            int ans = key[0];
            size[nod]--;
            for (int i = 0 ; i < size[nod] ; i++)
                key[i] = key[i + 1];
            return ans;
        }
        return *getKeyArray(nod);
    }

    Data findMax(int nod, bool deleteIt){
        while (!isLeaf(nod))
            nod = *(getSonArray(nod) + size[nod]);
        if (deleteIt)
            return *(getSonArray(nod) + (--size[nod]));
        return *(getKeyArray(nod) + size[nod] - 1);
    }

    void parcurge(int nod, void (*work)(Data)){
        Data *key = getKeyArray(nod);
        if (isLeaf(nod)){
            for (int i = 0 ; i < size[nod] ; i++)
                work( key[i] );
            return;
        }
        int *son = getSonArray(nod);
        for (int i = 0 ; i < size[nod] ; i++){
            parcurge(son[i], work);
            work(key[i]);
        }
        parcurge( son[ size[nod] ], work );
    }
public:
    Btree(){
        freeStack[0] = sizeof(freeStack) / sizeof(int) - 1;
        for (int i = 1 ; i <= freeStack[0] ; i++)
            freeStack[i] = i;

        root = allocNode();

        stepSize = 1;
        while (stepSize < T)
            stepSize <<= 1;
    }

    void insert(Data K){
        /*
        int nod = browseTree(K, true);
        Data *key = getKeyArray(nod);

        if (!isLeaf(nod) || key[ bSearch(key, K, size[nod]) ] == K)
            return;

        int index;
        for (index = size[nod] ; index && K < key[index - 1] ; index--)
            key[index] = key[index - 1];
        key[index] = K;
        size[nod]++;
        */
        int nod = browseTree(K, true);
        Data *key = getKeyArray(nod);

        int index = bSearch(key, K, size[nod]);

        if (key[index] == K){
            key[index].addOne();
            return;
        }

        for (index = size[nod] ; index && K < key[index - 1] ; index--)
            key[index] = key[index - 1];
        key[index] = K;
        size[nod]++;

    }

    bool contains(Data K){
        int nod = browseTree(K, false), *key = getKeyArray(nod);
        return  key[ bSearch(key, K, size[nod]) ] == K;
    }

    void erase(Data K){
        int nod = browseTree(K, false), *key = getKeyArray(nod);
        int index = bSearch(key, K, size[nod]);
        if (key[index] != K)
            return;

        if (isLeaf(nod)){
            for (int i = index + 1 ; i < size[nod] ; i++)
                key[i - 1] = key[i];
            size[nod]--;
            return;
        }

        int* son = getSonArray(nod);
        int st = son[index], dr = son[index + 1];
        if (T <= size[st]) {
            key[index] = findMax( st, true );
            return;
        }
        if (T <= size[dr]) {
            key[index] = findMin( dr, true );
            return;
        }

        Data *keySt = getKeyArray(st), *keyDr = getKeyArray(dr);
        int *sonSt = getSonArray(st), *sonDr = getSonArray(dr);

        key[index] = keySt[ size[st] - 1 ];
        son[index + 1] = sonDr[ size[dr] ];

        for (int i = size[st] - 1, j = 0 ; j < size[dr] ; i++, j++){
            keySt[i] = keyDr[j];
            sonSt[i] = sonDr[j];
        }

        size[st] += size[dr] - 1;
        dealloc(dr);
    }

    int getMinimum(){
        return findMin(root, false);
    }

    int getMaximum(){
        return findMax(root, false);
    }

    void inOrder( void (*work)(Data) ){
        parcurge(root, work);
    }
};

Btree<Per, 500000, 100> B;

ifstream in("algsort.in");
ofstream out("algsort.out");

void print(Per X){
    while (X.nr--)
        out << X.val << " ";
}

int main(){
    int n;
    Per P; P.nr = 1;

    in >> n;
    while (n--){
        in >> P.val;
        B.insert( P );
    }

    B.inOrder(print);
    out << '\n';

    return 0;
}