import java.io.IOException;
import java.util.Arrays;
import java.util.Random;
public class Main {
// сляние двух групп елементов одинокового размера
void mergegroup(int a[], int n, int st1, int st2, int st3) {
swapgroup(a, n, st1, st3);
int take1 = 0;
int take2 = 0;
for (int i = 0; i < 2 * n; i++) {
if ((take2 == n)
|| ((take1 < n) && (a[take1 + st3] < a[take2 + st2]))) {
int t = a[st1 + i];
a[st1 + i] = a[take1 + st3];
a[take1 + st3] = t;
take1++;
} else {
int t = a[st1 + i];
a[st1 + i] = a[take2 + st2];
a[take2 + st2] = t;
take2++;
}
}
}
// сортировка выбором
void slowsort(int a[], int st, int en) {
for (int i = st; i < en; i++)
for (int j = i + 1; j < en; j++) {
if (a[i] > a[j]) {
int k = a[i];
a[i] = a[j];
a[j] = k;
}
}
}
// обмен местами двух групп елементов одинакового размера
void swapgroup(int a[], int n, int st1, int st2) {
for (int i = 0; i < n; i++) {
int k = a[st1 + i];
a[st1 + i] = a[st2 + i];
a[st2 + i] = k;
}
}
//слияние
void merge(int[] a, int n) {
if (n <= 16) {
slowsort(a, 0, n);
return;
}
// разрез на группы длиной корень из n
int sizegroup
= (int) Math.
sqrt(n
); int remainder = n % sizegroup;
int numofgrp = n / sizegroup - 1;
// поиск конца первого массива
int posgap = 0;
while ((posgap < sizegroup * numofgrp) && (a[posgap] <= a[posgap + 1]))
posgap++;
// обмен группы содержащей конец первого массива с последней и обьединение с остатком
swapgroup(a, sizegroup, numofgrp * sizegroup, posgap - posgap
% sizegroup);
remainder += sizegroup;
// сортировка групп по первому елементу(в случае равенства по последнему)
for (int i = 0; i < numofgrp - 1; i++) {
int minnum = i;
for (int j = i + 1; j < numofgrp; j++)
if ((a[j * sizegroup] < a[minnum * sizegroup])
|| ((a[j * sizegroup] == a[minnum * sizegroup]) && (a[(j + 1)
* sizegroup - 1] < a[(minnum + 1) * sizegroup
- 1])))
minnum = j;
swapgroup(a, sizegroup, i * sizegroup, minnum * sizegroup);
}
// поочередное слияние групп
for (int i = 0; i < numofgrp - 1; i++) {
mergegroup(a, sizegroup, i * sizegroup, (i + 1) * sizegroup,
numofgrp * sizegroup);
}
// сортировка конца массива
slowsort(a, n - 2 * remainder, n);
// поочередное слияние групп в обратную сторону
for (int i = n - 2 * remainder; i >= remainder; i -= remainder)
mergegroup(a, remainder, i - remainder, i, n - remainder);
// сортировка начала и конца массива
slowsort(a, 0, 2 * remainder);
slowsort(a, n - remainder, n);
}
// сортировка
void sort(int[] a) {
int n = a.length;
for (int stp2 = 1; stp2 <= n; stp2 *= 2)
for (int i = 0; i < n; i += stp2) {
int size
= Math.
min(n, i
+ stp2
) - i
; swapgroup(a, size, 0, i); // для удобства реализации перемещаем
merge(a, size); // требуемый кусок масcива в начало
swapgroup(a, size, 0, i); // там его сортируем и возвращаем обратно
}
if (n > 16)
merge(a, n);
}
int n = 100000;
int[] a = new int[n];
for (int i = 0; i < n; i++)
a[i] = st.nextInt();
int[] b = a.clone();
sort(a);
for (int i = 0; i < n; i++)
if (a[i] != b[i])
throw new AssertionError();
};
for (int i = 0; i < 10; i++) {
testsort();
}
}
new Main().run();
}
}
aW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CmltcG9ydCBqYXZhLnV0aWwuQXJyYXlzOwppbXBvcnQgamF2YS51dGlsLlJhbmRvbTsKIApwdWJsaWMgY2xhc3MgTWFpbiB7CiAKIAogICAgICAgIC8vINGB0LvRj9C90LjQtSDQtNCy0YPRhSDQs9GA0YPQv9C/INC10LvQtdC80LXQvdGC0L7QsiDQvtC00LjQvdC+0LrQvtCy0L7Qs9C+INGA0LDQt9C80LXRgNCwCiAgICAgICAgdm9pZCBtZXJnZWdyb3VwKGludCBhW10sIGludCBuLCBpbnQgc3QxLCBpbnQgc3QyLCBpbnQgc3QzKSB7CiAgICAgICAgICAgICAgICBzd2FwZ3JvdXAoYSwgbiwgc3QxLCBzdDMpOwogICAgICAgICAgICAgICAgaW50IHRha2UxID0gMDsKICAgICAgICAgICAgICAgIGludCB0YWtlMiA9IDA7CiAgICAgICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IDIgKiBuOyBpKyspIHsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCh0YWtlMiA9PSBuKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfHwgKCh0YWtlMSA8IG4pICYmIChhW3Rha2UxICsgc3QzXSA8IGFbdGFrZTIgKyBzdDJdKSkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgdCA9IGFbc3QxICsgaV07CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYVtzdDEgKyBpXSA9IGFbdGFrZTEgKyBzdDNdOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFbdGFrZTEgKyBzdDNdID0gdDsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0YWtlMSsrOwogICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCB0ID0gYVtzdDEgKyBpXTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhW3N0MSArIGldID0gYVt0YWtlMiArIHN0Ml07CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYVt0YWtlMiArIHN0Ml0gPSB0OwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRha2UyKys7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICB9CiAKIAogICAgICAgIC8vINGB0L7RgNGC0LjRgNC+0LLQutCwINCy0YvQsdC+0YDQvtC8CiAgICAgICAgdm9pZCBzbG93c29ydChpbnQgYVtdLCBpbnQgc3QsIGludCBlbikgewogICAgICAgICAgICAgICAgZm9yIChpbnQgaSA9IHN0OyBpIDwgZW47IGkrKykKICAgICAgICAgICAgICAgICAgICAgICAgZm9yIChpbnQgaiA9IGkgKyAxOyBqIDwgZW47IGorKykgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChhW2ldID4gYVtqXSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50IGsgPSBhW2ldOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYVtpXSA9IGFbal07CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhW2pdID0gazsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICB9CiAKIAogICAgICAgIC8vINC+0LHQvNC10L0g0LzQtdGB0YLQsNC80Lgg0LTQstGD0YUg0LPRgNGD0L/QvyDQtdC70LXQvNC10L3RgtC+0LIg0L7QtNC40L3QsNC60L7QstC+0LPQviDRgNCw0LfQvNC10YDQsCAgICAKICAgICAgICB2b2lkIHN3YXBncm91cChpbnQgYVtdLCBpbnQgbiwgaW50IHN0MSwgaW50IHN0MikgewogICAgICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBuOyBpKyspIHsKICAgICAgICAgICAgICAgICAgICAgICAgaW50IGsgPSBhW3N0MSArIGldOwogICAgICAgICAgICAgICAgICAgICAgICBhW3N0MSArIGldID0gYVtzdDIgKyBpXTsKICAgICAgICAgICAgICAgICAgICAgICAgYVtzdDIgKyBpXSA9IGs7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgfQogCiAKICAgICAgICAvL9GB0LvQuNGP0L3QuNC1CiAgICAgICAgdm9pZCBtZXJnZShpbnRbXSBhLCBpbnQgbikgewogICAgICAgICAgICAgICAgaWYgKG4gPD0gMTYpIHsKICAgICAgICAgICAgICAgICAgICAgICAgc2xvd3NvcnQoYSwgMCwgbik7CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgLy8g0YDQsNC30YDQtdC3INC90LAg0LPRgNGD0L/Qv9GLINC00LvQuNC90L7QuSDQutC+0YDQtdC90Ywg0LjQtyBuCiAgICAgICAgICAgICAgICBpbnQgc2l6ZWdyb3VwID0gKGludCkgTWF0aC5zcXJ0KG4pOwogICAgICAgICAgICAgICAgaW50IHJlbWFpbmRlciA9IG4gJSBzaXplZ3JvdXA7CiAgICAgICAgICAgICAgICBpbnQgbnVtb2ZncnAgPSBuIC8gc2l6ZWdyb3VwIC0gMTsKICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgLy8g0L/QvtC40YHQuiDQutC+0L3RhtCwINC/0LXRgNCy0L7Qs9C+INC80LDRgdGB0LjQstCwCiAgICAgICAgICAgICAgICBpbnQgcG9zZ2FwID0gMDsKICAgICAgICAgICAgICAgIHdoaWxlICgocG9zZ2FwIDwgc2l6ZWdyb3VwICogbnVtb2ZncnApICYmIChhW3Bvc2dhcF0gPD0gYVtwb3NnYXAgKyAxXSkpCiAgICAgICAgICAgICAgICAgICAgICAgIHBvc2dhcCsrOwogICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgIC8vINC+0LHQvNC10L0g0LPRgNGD0L/Qv9GLINGB0L7QtNC10YDQttCw0YnQtdC5INC60L7QvdC10YYg0L/QtdGA0LLQvtCz0L4g0LzQsNGB0YHQuNCy0LAgINGBINC/0L7RgdC70LXQtNC90LXQuSDQuCDQvtCx0YzQtdC00LjQvdC10L3QuNC1INGBINC+0YHRgtCw0YLQutC+0LwKICAgICAgICAgICAgICAgIHN3YXBncm91cChhLCBzaXplZ3JvdXAsIG51bW9mZ3JwICogc2l6ZWdyb3VwLCBwb3NnYXAgLSBwb3NnYXAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAlIHNpemVncm91cCk7CiAgICAgICAgICAgICAgICByZW1haW5kZXIgKz0gc2l6ZWdyb3VwOwogICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAvLyDRgdC+0YDRgtC40YDQvtCy0LrQsCDQs9GA0YPQv9C/INC/0L4g0L/QtdGA0LLQvtC80YMg0LXQu9C10LzQtdC90YLRgyjQsiDRgdC70YPRh9Cw0LUg0YDQsNCy0LXQvdGB0YLQstCwINC/0L4g0L/QvtGB0LvQtdC00L3QtdC80YMpCiAgICAgICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IG51bW9mZ3JwIC0gMTsgaSsrKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGludCBtaW5udW0gPSBpOwogICAgICAgICAgICAgICAgICAgICAgICBmb3IgKGludCBqID0gaSArIDE7IGogPCBudW1vZmdycDsgaisrKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICgoYVtqICogc2l6ZWdyb3VwXSA8IGFbbWlubnVtICogc2l6ZWdyb3VwXSkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfHwgKChhW2ogKiBzaXplZ3JvdXBdID09IGFbbWlubnVtICogc2l6ZWdyb3VwXSkgJiYgKGFbKGogKyAxKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKiBzaXplZ3JvdXAgLSAxXSA8IGFbKG1pbm51bSArIDEpICogc2l6ZWdyb3VwCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAtIDFdKSkpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtaW5udW0gPSBqOwogICAgICAgICAgICAgICAgICAgICAgICBzd2FwZ3JvdXAoYSwgc2l6ZWdyb3VwLCBpICogc2l6ZWdyb3VwLCBtaW5udW0gKiBzaXplZ3JvdXApOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAvLyDQv9C+0L7Rh9C10YDQtdC00L3QvtC1INGB0LvQuNGP0L3QuNC1INCz0YDRg9C/0L8KICAgICAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbnVtb2ZncnAgLSAxOyBpKyspIHsKICAgICAgICAgICAgICAgICAgICAgICAgbWVyZ2Vncm91cChhLCBzaXplZ3JvdXAsIGkgKiBzaXplZ3JvdXAsIChpICsgMSkgKiBzaXplZ3JvdXAsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBudW1vZmdycCAqIHNpemVncm91cCk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgIC8vINGB0L7RgNGC0LjRgNC+0LLQutCwINC60L7QvdGG0LAg0LzQsNGB0YHQuNCy0LAKICAgICAgICAgICAgICAgIHNsb3dzb3J0KGEsIG4gLSAyICogcmVtYWluZGVyLCBuKTsKICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgLy8g0L/QvtC+0YfQtdGA0LXQtNC90L7QtSDRgdC70LjRj9C90LjQtSDQs9GA0YPQv9C/INCyINC+0LHRgNCw0YLQvdGD0Y4g0YHRgtC+0YDQvtC90YMgCiAgICAgICAgICAgICAgICBmb3IgKGludCBpID0gbiAtIDIgKiByZW1haW5kZXI7IGkgPj0gcmVtYWluZGVyOyBpIC09IHJlbWFpbmRlcikKICAgICAgICAgICAgICAgICAgICAgICAgbWVyZ2Vncm91cChhLCByZW1haW5kZXIsIGkgLSByZW1haW5kZXIsIGksIG4gLSByZW1haW5kZXIpOwogICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgIC8vINGB0L7RgNGC0LjRgNC+0LLQutCwINC90LDRh9Cw0LvQsCDQuCDQutC+0L3RhtCwINC80LDRgdGB0LjQstCwCiAgICAgICAgICAgICAgICBzbG93c29ydChhLCAwLCAyICogcmVtYWluZGVyKTsKICAgICAgICAgICAgICAgIHNsb3dzb3J0KGEsIG4gLSByZW1haW5kZXIsIG4pOwogICAgICAgIH0KIAogICAgICAgIC8vINGB0L7RgNGC0LjRgNC+0LLQutCwCiAgICAgICAgdm9pZCBzb3J0KGludFtdIGEpIHsKICAgICAgICAgICAgICAgIGludCBuID0gYS5sZW5ndGg7CiAgICAgICAgICAgICAgICBmb3IgKGludCBzdHAyID0gMTsgc3RwMiA8PSBuOyBzdHAyICo9IDIpCiAgICAgICAgICAgICAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbjsgaSArPSBzdHAyKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50IHNpemUgPSBNYXRoLm1pbihuLCBpICsgc3RwMikgLSBpOyAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3dhcGdyb3VwKGEsIHNpemUsIDAsIGkpOyAgICAgICAgICAgICAgLy8g0LTQu9GPINGD0LTQvtCx0YHRgtCy0LAg0YDQtdCw0LvQuNC30LDRhtC40Lgg0L/QtdGA0LXQvNC10YnQsNC10LwgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1lcmdlKGEsIHNpemUpOyAgICAgICAgICAgICAgICAgICAgICAgIC8vINGC0YDQtdCx0YPQtdC80YvQuSDQutGD0YHQvtC6INC80LDRgWPQuNCy0LAg0LIg0L3QsNGH0LDQu9C+CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3dhcGdyb3VwKGEsIHNpemUsIDAsIGkpOyAgICAgICAgICAgICAgLy8g0YLQsNC8INC10LPQviDRgdC+0YDRgtC40YDRg9C10Lwg0Lgg0LLQvtC30LLRgNCw0YnQsNC10Lwg0L7QsdGA0LDRgtC90L4KICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaWYgKG4gPiAxNikKICAgICAgICAgICAgICAgICAgICAgICAgbWVyZ2UoYSwgbik7CiAKICAgICAgICB9CiAKIAogICAgICAgIHZvaWQgdGVzdHNvcnQoKSB0aHJvd3MgSU9FeGNlcHRpb24gewogICAgICAgICAgICAgICAgaW50IG4gPSAxMDAwMDA7CiAgICAgICAgICAgICAgICBpbnRbXSBhID0gbmV3IGludFtuXTsKICAgICAgICAgICAgICAgIFJhbmRvbSBzdCA9IG5ldyBSYW5kb20oKTsKICAgICAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbjsgaSsrKQogICAgICAgICAgICAgICAgICAgICAgICBhW2ldID0gc3QubmV4dEludCgpOwogICAgICAgICAgICAgICAgaW50W10gYiA9IGEuY2xvbmUoKTsKICAgICAgICAgICAgICAgIEFycmF5cy5zb3J0KGIpOwogICAgICAgICAgICAgICAgc29ydChhKTsKICAgICAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbjsgaSsrKQogICAgICAgICAgICAgICAgICAgICAgICBpZiAoYVtpXSAhPSBiW2ldKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBBc3NlcnRpb25FcnJvcigpOwogICAgICAgIH07CiAKIAogICAgICAgIHZvaWQgcnVuKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKICAgICAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgMTA7IGkrKykgewogICAgICAgICAgICAgICAgICAgICAgICB0ZXN0c29ydCgpOwogICAgICAgICAgICAgICAgfQogICAgICAgIH0KIAogCiAgICAgICAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oU3RyaW5nW10gYXJncykgdGhyb3dzIElPRXhjZXB0aW9uIHsKICAgICAgICAgICAgICAgIG5ldyBNYWluKCkucnVuKCk7CiAgICAgICAgfQp9Cg==