Cod sursa(job #1753095)

Utilizator bciobanuBogdan Ciobanu bciobanu Data 5 septembrie 2016 20:19:03
Problema Sortare prin comparare Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 3.98 kb
#include <bits/stdc++.h>

using namespace std;

constexpr int kBuffSize = 4096;
constexpr int kBits = 8;
constexpr int kMask = (1 << kBits) - 1;
constexpr int kMaxN = 500000;

class InputReader {
public:
    InputReader(const char file_name[]) {
        fin = fopen(file_name, "rb");
        pos = kBuffSize;
    }

    template<class T>
    InputReader& operator >>(T &x) {
        char c;
        bool sign = false;
        do {
            c = get_char();
            sign |= (c == '-');
        } while (not isdigit(c));
        x = 0;
        do {
            x = (x << 1) + (x << 3) + (c & 207);
            c = get_char();
        } while (isdigit(c));
        if (sign) {
            x = -x;
        }
        return *this;
    }

private:
    FILE *fin;
    char buff[kBuffSize];
    int pos;

    inline char get_char() {
        if (pos == kBuffSize) {
            fread(buff, 1, kBuffSize, fin);
            pos = 0;
        }
        return buff[pos++];
    }
};

class OutputWriter {
public:
    OutputWriter(const char file_name[]) {
        fout = fopen(file_name, "wb");
        pos = 0;
    }

    ~OutputWriter() {
        fwrite(buff, 1, pos, fout);
        fclose(fout);
    }

    OutputWriter& operator <<(int X) {
        char digs[10];
        int n = 0, q;
        do {
            q = X / 10;
            digs[n++] = X - (q << 1) - (q << 3) + '0';
            X = q;
        } while (X);
        while (n--) {
            write_char(digs[n]);
        }
        return *this;
    }

    OutputWriter& operator <<(long long X) {
        char digs[20];
        int n = 0, q;
        do {
            q = X / 10;
            digs[n++] = X - (q << 1) - (q << 3) + '0';
            X = q;
        } while (X);
        while (n--) {
            write_char(digs[n]);
        }
        return *this;
    }

    OutputWriter& operator <<(const char &ch) {
        write_char(ch);
        return *this;
    }

private:
    FILE *fout;
    char buff[kBuffSize];
    int pos;

    inline void write_char(const char &ch) {
        buff[pos++] = ch;
        if (pos == kBuffSize) {
            fwrite(buff, 1, kBuffSize, stdout);
            pos = 0;
        }
    }
};

int v[kMaxN];

void insertionSort(const int lo, const int hi) {
    for (int i = lo + 1; i < hi; i += 1) {
        int x = v[i];
        int j = i;
        while (j > lo and v[j - 1] > x) {
            v[j] = v[j - 1];
            j -= 1;
        }
        v[j] = x;
    }
}

void radixPass(const int lo, const int hi, const int bits) {
    int b[1 << kBits], 
        e[1 << kBits] = {0};
    
    for (int i = lo; i < hi; i += 1) {
        e[(v[i] >> bits) & kMask] += 1;
    }
    b[0] = lo;
    e[0] += lo;
    for (int i = 1; i < (1 << kBits); i += 1) {
        b[i] = e[i - 1];
        e[i] += e[i - 1];
    }
    for (int i = 0; i < (1 << kBits); i += 1) {
        while (b[i] != e[i]) {
            int element = v[b[i]];
            int bucket = (element >> bits) & kMask;
            while (bucket != i) {
                int temporary = v[b[bucket]];
                v[b[bucket]++] = element;
                element = temporary;
                bucket = (element >> bits) & kMask;
            }
            v[b[i]++] = element;
        }
    }
    if (bits) {
        for (int i = 0; i < (1 << kBits); i += 1) {
            const int bucket_size = e[i] - (i ? e[i - 1] : lo);
            if (bucket_size > 100) {
                radixPass(e[i] - bucket_size, e[i], bits - kBits);
            } else {
                insertionSort(e[i] - bucket_size, e[i]);
            }
        }
    }
}

int main() {
    InputReader cin("algsort.in");
    ofstream cout("algsort.out");

    int n; cin >> n;
    for (int i = 0; i < n; i += 1) {
        cin >> v[i];
    }
    
    radixPass(0, n, 3 * kBits);

    for (int i = 0; i < n; i += 1) {
        cout << v[i] << ' ';
    }
    cout << '\n';
    return 0;
}