Skip to content

Commit 56906f5

Browse files
committed
Bitonic sort problems
1 parent 6480035 commit 56906f5

File tree

2 files changed

+57
-26
lines changed

2 files changed

+57
-26
lines changed

Baltic/Baltic 21-swaps.cpp

+37
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
/*
2+
Baltic 2021 The Collection Game
3+
- This is a buffed version of COI '21 MalnaRISC, so see that solution too
4+
- We basically want to sort the artworks by swapping them in parallel
5+
- https://en.wikipedia.org/wiki/Bitonic_sorter
6+
- https://en.wikipedia.org/wiki/Batcher_odd%E2%80%93even_mergesort
7+
- When a comparison returns 1, don't do anything because they've been sorted/swapped
8+
- When a comparison returns 0, manually swap the two artworks in the answer array
9+
- O(log^2 N) visits
10+
*/
11+
12+
#include "swaps.h"
13+
14+
#include <numeric>
15+
#include <algorithm>
16+
17+
void solve(int N, int V) {
18+
std::vector<int> ans(N);
19+
std::iota(ans.begin(), ans.end(), 1);
20+
int P2 = 1;
21+
while (P2 < N) P2 <<= 1;
22+
for (int P = 1; P < P2; P <<= 1)
23+
for (int k = P; k; k >>= 1) {
24+
std::vector<std::pair<int, int>> visited;
25+
for (int j = k % P; j < P2 - k; j += 2 * k)
26+
for (int i = 0; i < k && i + j + k < N; i++)
27+
if ((i + j) / (2 * P) == (i + j + k) / (2 * P)) {
28+
schedule(ans[i + j], ans[i + j + k]);
29+
visited.push_back({i + j, i + j + k});
30+
}
31+
std::vector<int> visit_res = visit();
32+
for (int i = 0; i < visit_res.size(); i++)
33+
if (!visit_res[i])
34+
std::swap(ans[visited[i].first], ans[visited[i].second]);
35+
}
36+
answer(ans);
37+
}

COI/COI 21-malnarisc.cpp

+20-26
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,26 @@
1-
#include <bits/stdc++.h>
2-
typedef long long ll;
3-
using namespace std;
1+
/*
2+
COI 2021 MalnaRISC
3+
- This is a nerfed version of Baltic '21 Swaps, so see that solution too
4+
- https://en.wikipedia.org/wiki/Bitonic_sorter
5+
- https://en.wikipedia.org/wiki/Batcher_odd%E2%80%93even_mergesort
6+
- O(log^2 N) steps to sort in parallel
7+
*/
48

5-
vector<pair<int, int>> swaps[5000];
6-
7-
int swapsort(int l, int r) {
8-
if (l == r) return 0;
9-
10-
int mid = (l + r) / 2;
11-
int depth = max(swapsort(l, mid), swapsort(mid + 1, r));
12-
13-
for (int i = 0; i <= mid - l; i++) {
14-
for (int x = mid, y = r + (mid - l != r - mid - 1) - i; x >= l + i; x--, y--)
15-
if (y <= r) swaps[depth + 1 + i].push_back({x, y});
16-
}
17-
return depth + mid - l + 1;
18-
}
9+
#include <stdio.h>
1910

2011
int main() {
21-
cin.tie(0)->sync_with_stdio(0);
2212
int n;
23-
cin >> n;
24-
int depth = swapsort(1, n);
25-
cout << depth << '\n';
26-
for (int i = 1; i <= depth; i++) {
27-
for (pair<int, int> j : swaps[i]) if (j.second <= n)
28-
cout << "CMPSWP R" << j.first << " R" << j.second << ' ';
29-
cout << '\n';
30-
}
13+
scanf("%d", &n);
14+
int p2 = 1, blocks = 0;
15+
while (p2 < n) p2 <<= 1, blocks++;
16+
printf("%d\n", blocks * (blocks + 1) / 2);
17+
for (int p = 1; p < p2; p <<= 1)
18+
for (int k = p; k; k >>= 1) {
19+
for (int j = k % p; j < p2 - k; j += 2 * k)
20+
for (int i = 0; i < k && i + j + k < n; i++)
21+
if ((i + j) / (2 * p) == (i + j + k) / (2 * p))
22+
printf("CMPSWP R%d R%d ", i + j + 1, i + j + k + 1);
23+
printf("\n");
24+
}
3125
return 0;
3226
}

0 commit comments

Comments
 (0)