#include <fstream>
#include <iostream>
#include <cstring>
#include <vector>
#include <sys/mman.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <fcntl.h>
#include <unistd.h>
using namespace std;
/**
{1}
`-.`'.-'
`-. .-'.
`-. -./\.- .-'
-. /_|\ .-
`-. `/____\' .-'.
`-. -./.-""-.\.- '
`-. /< (()) >\ .-'
- .`/__`-..-'__\' .-
,...`-./___|____|___\.-'.,.
,-' ,` . . ', `-,
,-' ________________ `-,
,'/____|_____|_____\
/ /__|_____|_____|___\
/ /|_____|_____|_____|_\
' /____|_____|_____|_____\
.' /__|_____|_____|_____|___\
,' /|_____|_____|_____|_____|_\
,,---''--...___...--'''--.. /../____|_____|_____|_____|_____\ ..--```--...___...--``---,,
'../__|_____|_____|_____|_____|___\
\ ) '.:/|_____|_____|_____|_____|_____|_\ ( /
)\ / ) ,':./____|_____|_____|_____|_____|_____\ ( \ /(
/ / ( ( /:../__|_____|_____|_____|_____|_____|___\ ) ) \ \
| | \ \ /.../|_____|_____|_____|_____|_____|_____|_\ / / | |
.-.\ \ \ \ '..:/____|_____|_____|_____|_____|_____|_____\ / / / /.-.
(= )\ `._.' | \:./ _ _ ___ ____ ____ _ _ _ _ _ _ _ __\ | `._.' /( =)
\ (_) ) \/ \ ( (_) /
\ `----' """""""""""""""""""""""""""""""""""""""""""""" `----' /
\ ____\__ __/____ /
\ (=\ \ / /-) /
\_)_\ \ / /_(_/
\ \ / /
) ) _ _ ( (
( (,-' `-..__ __..-' `-,) )
\_.-'' ``-..____ ____..-'' ``-._/
`-._ ``--...____...--'' _.-'
`-.._ _..-'
`-..__ OPUS DEI __..-'
``-..____ ____..-''
``--...____...--''
{1}
*/
class mapping_writer {
public:
mapping_writer() {
// DEFAULT C-TOR
};
mapping_writer(const char* file_name) {
fd = open(file_name, O_RDWR | O_CREAT, (mode_t)0600);
index &= 0;
buffers.push_back((char*)mmap(0, SIZE, PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0));
buffer_sizes.push_back(0);
active_buffer &= 0;
}
template <typename T>
inline mapping_writer& operator <<(T target) {
auto inc = [&, this]() mutable {
if (++index == SIZE) {
buffer_sizes[active_buffer] = index;
index &= 0;
buffers.push_back((char*)mmap(0, SIZE, PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0));
buffer_sizes.push_back(index);
++active_buffer;
}
};
aux &= 0;
if (target == 0) {
buffers[active_buffer][index] = '0';
inc();
return *this;
}
for (; target; target = target / 10)
nr[aux++] = target % 10 + '0';
for (; aux; inc())
buffers[active_buffer][index] = nr[--aux];
buffer_sizes[active_buffer] = index;
return *this;
}
inline mapping_writer& operator <<(const char* target) {
auto inc = [&, this]() mutable {
if (++index == SIZE) {
buffer_sizes[active_buffer] = index;
index &= 0;
buffers.push_back((char*)mmap(0, SIZE, PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0));
buffer_sizes.push_back(index);
++active_buffer;
}
};
aux &= 0;
for (; target[aux]; inc())
buffers[active_buffer][index] = target[aux++];
return *this;
}
~mapping_writer() {
size_t total_size = 0;
for (auto i : buffer_sizes)
total_size += i;
lseek(fd, total_size - 1, SEEK_SET);
write(fd, "", 1);
char* map = (char*)mmap(0, total_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
//char* map = (char *)malloc(total_size);
for (unsigned i = 0, accumulated = 0; i < buffers.size(); ++i) {
//fastMemcpy(map + accumulated, buffers[i], buffer_sizes[i]);
//cout << buffer_sizes[i] << endl;
//for (int j = 0; j < buffer_sizes[i]; ++j)
// cout << buffers[i][j];
//cout << endl;
memcpy(map + accumulated, buffers[i], buffer_sizes[i]);
munmap(buffers[i], buffer_sizes[i]);
accumulated += buffer_sizes[i];
}
//ofstream t("algsort.out");
//msync(map, total_size, MS_SYNC);
munmap(map, total_size);
//for (int i = 0; i < total_size; ++i)
// t << map[i];
//free(map);
close(fd);
}
private:
static const int SIZE = 0x200000;
std::vector<char*> buffers;
std::vector<size_t> buffer_sizes;
int fd, index, aux, active_buffer;
#ifdef SIGNED_WRITE
int sign;
#endif // SIGNED_WRITE
char nr[24];
};
class mapping_parser {
public:
inline mapping_parser() {
/// default c-tor
}
inline mapping_parser(const char* file_name) {
int fd = open(file_name, O_RDONLY);
index &= 0;
fstat(fd, &sb);
buffer = (char*)mmap(0, sb.st_size, PROT_READ, MAP_PRIVATE | MAP_NORESERVE, fd, 0);
close(fd);
}
template <typename T>
inline mapping_parser& operator >> (T& n) {
n &= 0;
for (; buffer[index] < '0' or buffer[index] > '9'; ++index);
for (; '0' <= buffer[index] and buffer[index] <= '9'; ++index)
n = (n << 3) + (n << 1) + buffer[index] - '0';
return *this;
}
~mapping_parser() {
munmap(buffer, sb.st_size);
}
private:
struct stat sb;
int index;
char* buffer;
};
mapping_parser f("algsort.in");
mapping_writer t("algsort.out");
#define WORD_SIZE 256
inline void radixSort(unsigned n, unsigned* A, unsigned* B, unsigned digit) {
unsigned frequence[WORD_SIZE]{}, index[WORD_SIZE];
index[0] = ~0;
#pragma GCC ivdep
for (unsigned i = 0; i < n; ++i)
++frequence[A[i] >> digit & (WORD_SIZE - 1)];
for (unsigned i = 1; i < WORD_SIZE; ++i) {
index[i] = index[i - 1] + frequence[i - 1];
}
#pragma GCC ivdep
for (unsigned i = 0; i < n; ++i)
B[++index[A[i] >> digit & (WORD_SIZE - 1)]] = A[i];
}
int main() {
unsigned n, v[500010], w[500010];
f >> n;
#pragma GCC ivdep
for (uint32_t i = 0; i < n; ++i)
f >> v[i];
radixSort(n, v, w, 0);
radixSort(n, w, v, 8);
radixSort(n, v, w, 16);
radixSort(n, w, v, 24);
#pragma GCC ivdep
for (uint32_t i = 0; i < n; ++i)
t << v[i] << " ";
return 0;
}