Cod sursa(job #1886133)

Utilizator Kln1000Ciobanu Bogdan Kln1000 Data 20 februarie 2017 18:07:28
Problema Sortare prin comparare Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 6.17 kb
#include <vector>
#include <fstream>
#include <queue>

#define BITS 8
#define MASK ((1<<BITS)-1)
#define THRESHOLD 64

using namespace std;

/**

                                          `-.`'.-'
                                       `-.        .-'.
                                    `-.    -./\.-    .-'
                                        -.  /_|\  .-
                                    `-.   `/____\'   .-'.
                                 `-.    -./.-""-.\.-      '
                                    `-.  /< (()) >\  .-'
                                  -   .`/__`-..-'__\'   .-
                                ,...`-./___|____|___\.-'.,.
                                   ,-'   ,` . . ',   `-,
                                ,-'   ________________  `-,
                                   ,'/____|_____|_____\
                                  / /__|_____|_____|___\
                                 / /|_____|_____|_____|_\
                                ' /____|_____|_____|_____\
                              .' /__|_____|_____|_____|___\
                             ,' /|_____|_____|_____|_____|_\
,,---''--...___...--'''--.. /../____|_____|_____|_____|_____\ ..--```--...___...--``---,,
                           '../__|_____|_____|_____|_____|___\
      \    )              '.:/|_____|_____|_____|_____|_____|_\               (    /
      )\  / )           ,':./____|_____|_____|_____|_____|_____\             ( \  /(
     / / ( (           /:../__|_____|_____|_____|_____|_____|___\             ) ) \ \
    | |   \ \         /.../|_____|_____|_____|_____|_____|_____|_\           / /   | |
 .-.\ \    \ \       '..:/____|_____|_____|_____|_____|_____|_____\         / /    / /.-.
(=  )\ `._.' |       \:./ _  _ ___  ____  ____ _    _ _ _ _ _  _ __\        | `._.' /(  =)
 \ (_)       )        \/                                            \       (       (_) /
  \    `----'          """"""""""""""""""""""""""""""""""""""""""""""        `----'    /
   \   ____\__                                                              __/____   /
    \ (=\     \                                                            /     /-) /
     \_)_\     \                                                         /     /_(_/
          \     \                                                        /     /
           )     )  _                                                _  (     (
          (     (,-' `-..__                                    __..-' `-,)     )
           \_.-''          ``-..____                  ____..-''          ``-._/
            `-._                    ``--...____...--''                    _.-'
                `-.._                                                _..-'
                     `-..__          CIOBY KNOWS ALL           __..-'
                           ``-..____                  ____..-''
                                    ``--...____...--''

*/

class parser{
    public:
        parser() {}
        parser(const char *file_name){
            input_file.open(file_name,ios::in | ios::binary);
            input_file.sync_with_stdio(false);
            index=0;
            input_file.read(buffer,SIZE);}///I/O iterators?
        inline parser &operator >>(int &n){
            for (;buffer[index]<'0' or buffer[index]>'9';inc());
            n=0;
            for (;'0'<=buffer[index] and buffer[index]<='9';inc())
                n=10*n+buffer[index]-'0';
            return *this;}
    private:
        fstream input_file;
        static const int SIZE=0x400000;
        char buffer[SIZE];
        int index=0;
        inline void inc(){
            if(++index==SIZE)
                index=0,input_file.read(buffer,SIZE);}
};

class writer{
    public:
        writer() {};
        writer(const char *file_name){
            output_file.open(file_name,ios::out | ios::binary);
            output_file.sync_with_stdio(false);
            index=0;}
        inline writer &operator <<(int target){
            aux=0;
            n=target;
            if (!n)
                nr[aux++]='0';
            for (;n;n/=10)
                nr[aux++]=n%10+'0';
            for(;aux;inc())
                buffer[index]=nr[--aux];
            return *this;}
        inline writer &operator <<(const char *target){
            aux=0;
            while (target[aux])
                buffer[index]=target[aux++],inc();
            return *this;}
        ~writer(){
            output_file.write(buffer,index);}///convert to stringstream?
    private:
        ofstream output_file;
        static const int SIZE=0x100000;///optimal 0x200000 0x100000
        int index=0,aux,n;
        char buffer[SIZE],nr[24];
        inline void inc(){
            if(++index==SIZE)
                index=0,output_file.write(buffer,SIZE);}
};

parser f ("algsort.in");
writer t ("algsort.out");

vector <int> v;
int n;

inline void insertionSort(int lo, int hi) {
  for (int i = lo; i < hi; i++) {
    int x = v[i];
    int j = i;
    while ((j > lo) && (v[j - 1] > x)) {
      v[j] = v[j - 1];
      j--;
    }
    v[j] = x;
  }
}
void radixSort(int lo, int hi, int bits) {
  int ptr[1 << BITS], end[1 << BITS] = { };

  for (int i = lo; i < hi; i++) {
    end[(v[i] >> bits) & MASK]++;
  }
  ptr[0] = lo;
  end[0] += lo;
  for (int i = 1; i < (1 << BITS); i++) {
    ptr[i] = end[i - 1];
    end[i] += end[i - 1];
  }
  for (int i = 0; i < (1 << BITS); i++) {
    while (ptr[i] != end[i]) {
      int elem = v[ptr[i]];
      int bucket = (elem >> bits) & MASK;
      while (bucket != i) {
        int tmp = v[ptr[bucket]];
        v[ptr[bucket]++] = elem;
        elem = tmp;
        bucket = (elem >> bits) & MASK;
      }
      v[ptr[i]++] = elem;
    }
  }
  if (bits) {
    for (int i = 0; i < (1 << BITS); i++) {
      int size = end[i] - (i ? end[i - 1] : lo);
      if (size > THRESHOLD) {
        radixSort(end[i] - size, end[i], bits - BITS);
      } else if (size > 1) {
        insertionSort(end[i] - size, end[i]);
      }
    }
  }
}

int main()
{
    f>>n;
    v.resize(n);
    for (auto &i:v)
        f>>i;
    radixSort(0, n, 24);
    for (auto i:v)
        t<<i<<" ";
    return 0;
}