Cod sursa(job #2445970)

Utilizator ShayTeodor Matei Shay Data 6 august 2019 15:25:44
Problema Sortare prin comparare Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 3.33 kb
#include <fstream>
#include <algorithm>
#include <math.h>
#include <assert.h>

#define BUFFER_SIZE 1 << 17

char buffer[BUFFER_SIZE];
int pos = BUFFER_SIZE;
int n;

inline char next() {
    if (pos == BUFFER_SIZE) {
        fread(buffer, 1, BUFFER_SIZE, stdin);
        pos = 0;
    }

    return buffer[pos++];
}

inline void print(int n) {
    char snum[65];
    int i = 0;
    do {
        snum[i++] = n % 10 + '0';
        n /= 10;
    } while (n);

    --i;

    while (i >= 0) {
        putchar(snum[i--]);
    }

    putchar(' ');
}

inline int next_int() {
    int n = 0;
    char c = next();
    
    while (!('0' <= c && c <= '9')) {
        c = next();
    }
    
    while ('0' <= c && c <= '9') {
        n = (n << 3) + (n << 1) + (c - '0');
        c = next();
    }

    return n;
}

inline void swap(int *a, int *b) {
    int *temp = std::move(a);
    a = std::move(b);
    b = std::move(temp);
}

inline int binarySearch(int a[], int item, int low, int high) { 
    if (high <= low) 
        return (item > a[low])?  (low + 1): low; 
  
    int mid = (low + high)/2; 
  
    if(item == a[mid]) 
        return mid+1; 
  
    if(item > a[mid]) 
        return binarySearch(a, item, mid+1, high); 
    return binarySearch(a, item, low, mid-1); 
} 

inline void insertion_sort(int v[], int *begin, int *end) {
    int left = begin - v;
    int right = end - v;
    int location, element, j;
    for (int i = left + 1; i <= right ; ++i) {
        element = v[i];
        j = i - 1;

        location = binarySearch(v, element, 0, j);

        while ( j >= location) {
            v[j + 1] = v[j];
            --j;
        }

        v[j + 1] = element;
    }

    return;
}

inline int* partition(int v[], int low, int high) {
    int pivot = v[high];
    int i = low - 1;

    for (int j = low ; j < high ; ++j) {
        if (v[j] <= pivot) {
            ++i;
            std::swap(v[i], v[j]);
        }
    }

    std::swap(v[i + 1], v[high]);

    return (v + i + 1);
}

inline int* median(int v[], int *a, int *b, int *c) {
    int max = std::max(std::max(v[*a], v[*b]), v[*c]);
    int min = std::min(std::min(v[*a], v[*b]), v[*c]);
    int median = max ^ min ^ v[*a] ^ v[*b] ^ v[*c];

    if (median == v[*a]) {
        return a;
    }

    if (median == v[*b]) {
        return b;
    }

    return c;
}

inline void intro_sort_utils(int v[], int *begin, int *end, int max_depth) {
    int size = end - begin;

    if (size < 16) {
        insertion_sort(v, begin, end);
        return;
    }

    if (max_depth == 0) {
        std::make_heap(begin, end + 1);
        std::sort_heap(begin, end + 1);
        return;
    }

    int *pivot = median(v, begin, begin + size / 2, end);

    swap(pivot, end);
    int *partition_point = partition(v, begin - v, end - v);
    intro_sort_utils(v, begin, partition_point - 1, max_depth - 1);
    intro_sort_utils(v, partition_point + 1, end, max_depth - 1);

    return;
}

inline void intro_sort(int v[], int *begin, int *end) {
    int max_depth = 2 * log(end - begin);
    intro_sort_utils(v, begin, end, max_depth);
    return;
}

int main() {
    freopen("algsort.in", "r", stdin);
    freopen("algsort.out", "w", stdout);
    
    n = next_int();
    int v[n];

    for (int i = 0 ; i < n ; ++i) {
        v[i] = next_int();
    }

    intro_sort(v, v, v + n - 1);

    for (int i = 0 ; i < n ; ++i) {
        print(v[i]);
    }


    return 0;
}