归并排序
归并排序
1、二分归并排序可以算出一个数组中的逆序对数目,因为本身这个算法利用的就是分治算法,所以可以在 \(nlogn\) 的时间复杂度里面求出所有逆序对数目。
2、另外我还拓展了一些三分归并、四分归并...等等,目前没发现有啥用途,然后我又写了个代码,支持最多 \(31\) 分归并排序,通过这个代码测试,可以发现六分归并在所有归并中是最快的,个人测试,正确性不保证$。
template<typename T>
struct Gb{
vector<T> c, d;
Gb(int n) : c(n + 1), d(n + 1) {}
// 二分归并排序(可求逆序对数目)
inline T Msort2(int l, int r, vector<T> &a) {
T ans{};
if (l == r) return ans;
int mid = (l + r) >> 1;
int i = l, j = mid + 1, cnt = l;
ans += Msort2(l, mid, a); ans += Msort2(j, r, a);
while (i <= mid && j <= r) {
if (a[i] <= a[j]) c[cnt++] = a[i++];
else c[cnt++] = a[j++], ans += (mid - i + 1);
}
while (i <= mid) c[cnt++] = a[i++];
while (j <= r) c[cnt++] = a[j++];
for (int k = l; k <= r; k++) a[k] = c[k];
return ans;
}
// 三分归并排序(用途未知)
inline void Msort3(int l, int r, vector<T> &a) {
int len = r - l + 1;
if (len <= 2) {
d[l] = min(a[l], a[r]);
d[r] = max(a[l], a[r]);
for (int i = l; i <= r; i++) a[i] = d[i];
return;
}
int l1 = l, l2 = l1 + (len / 3), l3 = l2 + (len / 3), r1 = l2 - 1, r2 = l3 - 1, r3 = r, cnt = l;
Msort3(l1, r1, a); Msort3(l2, r2, a); Msort3(l3, r3, a);
while (l1 <= r1 && l2 <= r2 && l3 <= r3) {
if (a[l1] <= a[l2] && a[l1] <= a[l3]) d[cnt++] = a[l1++];
else if (a[l2] <= a[l1] && a[l2] <= a[l3]) d[cnt++] = a[l2++];
else d[cnt++] = a[l3++];
}
while (l1 <= r1 && l2 <= r2) {
if (a[l1] <= a[l2]) d[cnt++] = a[l1++];
else d[cnt++] = a[l2++];
}
while (l1 <= r1 && l3 <= r3) {
if (a[l1] <= a[l3]) d[cnt++] = a[l1++];
else d[cnt++] = a[l3++];
}
while (l2 <= r2 && l3 <= r3) {
if (a[l2] <= a[l3]) d[cnt++] = a[l2++];
else d[cnt++] = a[l3++];
}
while (l1 <= r1) d[cnt++] = a[l1++];
while (l2 <= r2) d[cnt++] = a[l2++];
while (l3 <= r3) d[cnt++] = a[l3++];
for (int i = l; i <= r; i++) a[i] = d[i];
}
// 四分归并排序(用途未知)
inline void Msort4(int l, int r, vector<T> &a) {
if (r - l + 1 <= 3) {
for (int i = l + 1; i <= r; i++) {
T t = a[i];
int j = i - 1;
while (j >= l && t < a[j]) {
a[j + 1] = a[j];
j--;
}
a[j + 1] = t;
}
return;
}
int len = r - l + 1;
int l1 = l, l2 = l1 + (len / 4), l3 = l2 + (len / 4), l4 = l3 + (len / 4), r1 = l2 - 1, r2 = l3 - 1, r3 = l4 - 1, r4 = r, cnt = l;
Msort4(l1, r1, a); Msort4(l2, r2, a); Msort4(l3, r3, a); Msort4(l4, r4, a);
while (l1 <= r1 && l2 <= r2 && l3 <= r3 && l4 <= r4) {
if (a[l1] <= a[l2] && a[l1] <= a[l3] && a[l1] <= a[l4]) d[cnt++] = a[l1++];
else if (a[l2] <= a[l1] && a[l2] <= a[l3] && a[l2] <= a[l4]) d[cnt++] = a[l2++];
else if (a[l3] <= a[l1] && a[l3] <= a[l2] && a[l3] <= a[l4]) d[cnt++] = a[l3++];
else d[cnt++] = a[l4++];
}
while (l1 <= r1 && l2 <= r2 && l3 <= r3) {
if (a[l1] <= a[l2] && a[l1] <= a[l3]) d[cnt++] = a[l1++];
else if (a[l2] <= a[l1] && a[l2] <= a[l3]) d[cnt++] = a[l2++];
else d[cnt++] = a[l3++];
}
while (l1 <= r1 && l2 <= r2 && l4 <= r4) {
if (a[l1] <= a[l2] && a[l1] <= a[l4]) d[cnt++] = a[l1++];
else if (a[l2] <= a[l1] && a[l2] <= a[l4]) d[cnt++] = a[l2++];
else d[cnt++] = a[l4++];
}
while (l1 <= r1 && l4 <= r4 && l3 <= r3) {
if (a[l1] <= a[l4] && a[l1] <= a[l3]) d[cnt++] = a[l1++];
else if (a[l4] <= a[l1] && a[l4] <= a[l3]) d[cnt++] = a[l4++];
else d[cnt++] = a[l3++];
}
while (l4 <= r4 && l2 <= r2 && l3 <= r3) {
if (a[l4] <= a[l2] && a[l4] <= a[l3]) d[cnt++] = a[l4++];
else if (a[l2] <= a[l4] && a[l2] <= a[l3]) d[cnt++] = a[l2++];
else d[cnt++] = a[l3++];
}
while (l1 <= r1 && l2 <= r2) {
if (a[l1] <= a[l2]) d[cnt++] = a[l1++];
else d[cnt++] = a[l2++];
}
while (l1 <= r1 && l3 <= r3) {
if (a[l1] <= a[l3]) d[cnt++] = a[l1++];
else d[cnt++] = a[l3++];
}
while (l1 <= r1 && l4 <= r4) {
if (a[l1] <= a[l4]) d[cnt++] = a[l1++];
else d[cnt++] = a[l4++];
}
while (l2 <= r2 && l3 <= r3) {
if (a[l2] <= a[l3]) d[cnt++] = a[l2++];
else d[cnt++] = a[l3++];
}
while (l2 <= r2 && l4 <= r4) {
if (a[l2] <= a[l4]) d[cnt++] = a[l2++];
else d[cnt++] = a[l4++];
}
while (l3 <= r3 && l4 <= r4) {
if (a[l3] <= a[l4]) d[cnt++] = a[l3++];
else d[cnt++] = a[l4++];
}
while (l1 <= r1) d[cnt++] = a[l1++];
while (l2 <= r2) d[cnt++] = a[l2++];
while (l3 <= r3) d[cnt++] = a[l3++];
while (l4 <= r4) d[cnt++] = a[l4++];
for (int i = l; i <= r; i++) a[i] = d[i];
}
};
void solve() {
// int n;
// read(n);
// vector<i64> a(n + 1);
// for (int i = 1; i <= n; i++) read(a[i]);
// Gb<i64> t(n);
// cout << t.Msort2(1, n, a) << '\n';
// int n;
// read(n);
// vector<i64> a(n + 1);
// for (int i = 1; i <= n; i++) read(a[i]);
// Gb<i64> t(n);
// t.Msort3(1, n, a);
// for (int i = 1; i <= n; i++) cout << a[i] << ' ';
}
多分归并排序:
template<typename T>
struct Gb{
vector<T> c, d;
Gb(int n) : c(n + 1), d(n + 1) {}
// 二分归并排序(可求逆序对数目)
inline T Msort2(int l, int r, vector<T> &a) {
T ans{};
if (l == r) return ans;
int mid = (l + r) >> 1;
int i = l, j = mid + 1, cnt = l;
ans += Msort2(l, mid, a); ans += Msort2(j, r, a);
while (i <= mid && j <= r) {
if (a[i] <= a[j]) c[cnt++] = a[i++];
else c[cnt++] = a[j++], ans += (mid - i + 1);
}
while (i <= mid) c[cnt++] = a[i++];
while (j <= r) c[cnt++] = a[j++];
for (int k = l; k <= r; k++) a[k] = c[k];
return ans;
}
// 三分归并排序(用途未知)
inline void Msort3(int l, int r, vector<T> &a) {
int len = r - l + 1;
if (len <= 2) {
d[l] = min(a[l], a[r]);
d[r] = max(a[l], a[r]);
for (int i = l; i <= r; i++) a[i] = d[i];
return;
}
int l1 = l, l2 = l1 + (len / 3), l3 = l2 + (len / 3), r1 = l2 - 1, r2 = l3 - 1, r3 = r, cnt = l;
Msort3(l1, r1, a); Msort3(l2, r2, a); Msort3(l3, r3, a);
while (l1 <= r1 && l2 <= r2 && l3 <= r3) {
if (a[l1] <= a[l2] && a[l1] <= a[l3]) d[cnt++] = a[l1++];
else if (a[l2] <= a[l1] && a[l2] <= a[l3]) d[cnt++] = a[l2++];
else d[cnt++] = a[l3++];
}
while (l1 <= r1 && l2 <= r2) {
if (a[l1] <= a[l2]) d[cnt++] = a[l1++];
else d[cnt++] = a[l2++];
}
while (l1 <= r1 && l3 <= r3) {
if (a[l1] <= a[l3]) d[cnt++] = a[l1++];
else d[cnt++] = a[l3++];
}
while (l2 <= r2 && l3 <= r3) {
if (a[l2] <= a[l3]) d[cnt++] = a[l2++];
else d[cnt++] = a[l3++];
}
while (l1 <= r1) d[cnt++] = a[l1++];
while (l2 <= r2) d[cnt++] = a[l2++];
while (l3 <= r3) d[cnt++] = a[l3++];
for (int i = l; i <= r; i++) a[i] = d[i];
}
// 四分归并排序(用途未知)
inline void Msort4(int l, int r, vector<T> &a) {
if (r - l + 1 <= 3) {
for (int i = l + 1; i <= r; i++) {
T t = a[i];
int j = i - 1;
while (j >= l && t < a[j]) {
a[j + 1] = a[j];
j--;
}
a[j + 1] = t;
}
return;
}
int len = r - l + 1;
int l1 = l, l2 = l1 + (len / 4), l3 = l2 + (len / 4), l4 = l3 + (len / 4), r1 = l2 - 1, r2 = l3 - 1, r3 = l4 - 1, r4 = r, cnt = l;
Msort4(l1, r1, a); Msort4(l2, r2, a); Msort4(l3, r3, a); Msort4(l4, r4, a);
while (l1 <= r1 && l2 <= r2 && l3 <= r3 && l4 <= r4) {
if (a[l1] <= a[l2] && a[l1] <= a[l3] && a[l1] <= a[l4]) d[cnt++] = a[l1++];
else if (a[l2] <= a[l1] && a[l2] <= a[l3] && a[l2] <= a[l4]) d[cnt++] = a[l2++];
else if (a[l3] <= a[l1] && a[l3] <= a[l2] && a[l3] <= a[l4]) d[cnt++] = a[l3++];
else d[cnt++] = a[l4++];
}
while (l1 <= r1 && l2 <= r2 && l3 <= r3) {
if (a[l1] <= a[l2] && a[l1] <= a[l3]) d[cnt++] = a[l1++];
else if (a[l2] <= a[l1] && a[l2] <= a[l3]) d[cnt++] = a[l2++];
else d[cnt++] = a[l3++];
}
while (l1 <= r1 && l2 <= r2 && l4 <= r4) {
if (a[l1] <= a[l2] && a[l1] <= a[l4]) d[cnt++] = a[l1++];
else if (a[l2] <= a[l1] && a[l2] <= a[l4]) d[cnt++] = a[l2++];
else d[cnt++] = a[l4++];
}
while (l1 <= r1 && l4 <= r4 && l3 <= r3) {
if (a[l1] <= a[l4] && a[l1] <= a[l3]) d[cnt++] = a[l1++];
else if (a[l4] <= a[l1] && a[l4] <= a[l3]) d[cnt++] = a[l4++];
else d[cnt++] = a[l3++];
}
while (l4 <= r4 && l2 <= r2 && l3 <= r3) {
if (a[l4] <= a[l2] && a[l4] <= a[l3]) d[cnt++] = a[l4++];
else if (a[l2] <= a[l4] && a[l2] <= a[l3]) d[cnt++] = a[l2++];
else d[cnt++] = a[l3++];
}
while (l1 <= r1 && l2 <= r2) {
if (a[l1] <= a[l2]) d[cnt++] = a[l1++];
else d[cnt++] = a[l2++];
}
while (l1 <= r1 && l3 <= r3) {
if (a[l1] <= a[l3]) d[cnt++] = a[l1++];
else d[cnt++] = a[l3++];
}
while (l1 <= r1 && l4 <= r4) {
if (a[l1] <= a[l4]) d[cnt++] = a[l1++];
else d[cnt++] = a[l4++];
}
while (l2 <= r2 && l3 <= r3) {
if (a[l2] <= a[l3]) d[cnt++] = a[l2++];
else d[cnt++] = a[l3++];
}
while (l2 <= r2 && l4 <= r4) {
if (a[l2] <= a[l4]) d[cnt++] = a[l2++];
else d[cnt++] = a[l4++];
}
while (l3 <= r3 && l4 <= r4) {
if (a[l3] <= a[l4]) d[cnt++] = a[l3++];
else d[cnt++] = a[l4++];
}
while (l1 <= r1) d[cnt++] = a[l1++];
while (l2 <= r2) d[cnt++] = a[l2++];
while (l3 <= r3) d[cnt++] = a[l3++];
while (l4 <= r4) d[cnt++] = a[l4++];
for (int i = l; i <= r; i++) a[i] = d[i];
}
// n分归并排序(用途未知,2<=n<=30)
inline void EXsort(int l, int r, vector<T> &a, const int path_num) {
T ans = 0ll;
int len = r - l + 1;
T *ptr = a.data();
if (len < path_num) {
for (int i = l + 1; i <= r; i++) {
T t = ptr[i];
int j = i - 1;
while (j >= l && t < ptr[j]) {
ptr[j + 1] = ptr[j];
j--;
}
ptr[j + 1] = t;
}
return;
}
static int dep = -1;
static int bak[64][32];
int *L = *(bak + ++dep), *R = *(bak + ++dep);
L[0] = l;
for (int i = 1; i < path_num; i++) L[i] = L[i - 1] + len / path_num;
R[path_num - 1] = r;
for (int i = path_num - 2; i >= 0; i--) R[i] = L[i + 1] - 1;
for (int i = 0; i < path_num; i++) EXsort(L[i], R[i], a, path_num);
int cnt = l;
int s = (1 << path_num) - 1;
while (s) {
int i = s;
int mx = __lg(i & -i);
i -= i & -i;
while (i) {
int j = i & -i, k = __lg(j);
if (ptr[L[mx]] > ptr[L[k]]) {
mx = k;
}
i -= j;
}
d[cnt++] = ptr[L[mx]];
if (++L[mx] > R[mx]) {
s &= ~(1 << mx);
}
}
dep -= 2;
for (int i = l; i <= r; i++) ptr[i] = d[i];
}
};
void solve() {
int n;
cin >> n;
vector<int> a(n + 1);
for (int i = 1; i <= n; i++) {
cin >> a[i];
}
Gb<int> gb(n);
int fen = 12;
gb.EXsort(1, n, a, fen);
for (int i = 1; i < a.size(); i++) cout << a[i] << ' ';
}

浙公网安备 33010602011771号