#include <fstream>
#include <cstring>
#include <vector>
#include <sys/mman.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <fcntl.h>
#include <unistd.h>
#define BITS 8
#define MASK ((1<<BITS)-1)
#define THRESHOLD 64
using namespace std;
/**
{1}
`-.`'.-'
`-. .-'.
`-. -./\.- .-'
-. /_|\ .-
`-. `/____\' .-'.
`-. -./.-""-.\.- '
`-. /< (()) >\ .-'
- .`/__`-..-'__\' .-
,...`-./___|____|___\.-'.,.
,-' ,` . . ', `-,
,-' ________________ `-,
,'/____|_____|_____\
/ /__|_____|_____|___\
/ /|_____|_____|_____|_\
' /____|_____|_____|_____\
.' /__|_____|_____|_____|___\
,' /|_____|_____|_____|_____|_\
,,---''--...___...--'''--.. /../____|_____|_____|_____|_____\ ..--```--...___...--``---,,
'../__|_____|_____|_____|_____|___\
\ ) '.:/|_____|_____|_____|_____|_____|_\ ( /
)\ / ) ,':./____|_____|_____|_____|_____|_____\ ( \ /(
/ / ( ( /:../__|_____|_____|_____|_____|_____|___\ ) ) \ \
| | \ \ /.../|_____|_____|_____|_____|_____|_____|_\ / / | |
.-.\ \ \ \ '..:/____|_____|_____|_____|_____|_____|_____\ / / / /.-.
(= )\ `._.' | \:./ _ _ ___ ____ ____ _ _ _ _ _ _ _ __\ | `._.' /( =)
\ (_) ) \/ \ ( (_) /
\ `----' """""""""""""""""""""""""""""""""""""""""""""" `----' /
\ ____\__ __/____ /
\ (=\ \ / /-) /
\_)_\ \ / /_(_/
\ \ / /
) ) _ _ ( (
( (,-' `-..__ __..-' `-,) )
\_.-'' ``-..____ ____..-'' ``-._/
`-._ ``--...____...--'' _.-'
`-.._ _..-'
`-..__ CIOBY KNOWS ALL __..-'
``-..____ ____..-''
``--...____...--''
{1}
*/
class mapping_parser {
public:
inline mapping_parser() {
/// default c-tor
}
inline mapping_parser(const char* file_name) {
int fd = open(file_name, O_RDONLY);
block_number &= 0;
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:
static const int SIZE = 0x400000; /// 4MB
struct stat sb;
int block_number, index;
char* buffer;
};
#pragma GCC diagnostic ignored "-Wunused-result"
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) {
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) {
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;
while (target[aux])
buffers[active_buffer][index] = target[aux++], inc();
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);
for (unsigned i = 0, accumulated = 0; i < buffers.size(); ++i) {
memcpy(map + accumulated, buffers[i], buffer_sizes[i]);
munmap(buffers[i], buffer_sizes[i]);
accumulated += buffer_sizes[i];
}
msync(map, total_size, MS_SYNC);
munmap(map, total_size);
close(fd);
}
private:
static const int SIZE = 5242880;
std::vector<char*> buffers;
std::vector<size_t> buffer_sizes;
int fd, index, aux, active_buffer;
char nr[24];
};
mapping_parser f("algsort.in");
mapping_writer t("algsort.out");
int n, v[500010];
inline void insertionSort(int low, int up) {
for (int i = low; i < up; ++i) {
int x = v[i];
int j = i;
while ((j > low) and (v[j - 1] > x)) {
v[j] = v[j - 1];
--j;
}
v[j] = x;
}
}
void radixSort(int low, int up, int bits) {
int ptr[1 << BITS], bucket[1 << BITS] = { };
for (int i = low; i < up; ++i)
++bucket[(v[i] >> bits)& MASK];
ptr[0] = low;
bucket[0] += low;
for (int i = 1; i < (1 << BITS); ++i) {
ptr[i] = bucket[i - 1];
bucket[i] += bucket[i - 1];
}
for (int i = 0; i < (1 << BITS); ++i) {
while (ptr[i] != bucket[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 = bucket[i] - (i ? bucket[i - 1] : low);
if (size > THRESHOLD)
radixSort(bucket[i] - size, bucket[i], bits - BITS);
else if (size > 1)
insertionSort(bucket[i] - size, bucket[i]);
}
}
}
int main()
{
f >> n;
for (int i = 0; i < n; ++i)
f >> v[i];
radixSort(0, n, 24);
for (int i = 0; i < n; ++i)
t << v[i] << " ";
return 0;
}