题解:CF2101B Quartet Swapping
Claire0918 · · 题解
首先我们注意到奇数位和偶数位是独立的,将其分开考虑。我们考虑贪心地从前向后要求每一位最小,也就是从小到大枚举
令
我们发现对于
使用链表维护
Code:
#include<bits/stdc++.h>
#define mem(a, v) memset(a, v, sizeof(a))
using namespace std;
const int maxn = 2e5 + 10;
int t, n;
int a[maxn], nxt[maxn], pre[maxn], ord1[maxn], ord2[maxn];
int main(){
scanf("%d", &t), a[0] = 1e9;
while (t--){
scanf("%d", &n), nxt[0] = 1, fill(ord1 + 1, ord1 + n + 1, 0), fill(ord2 + 1, ord2 + n + 1, 0);
for (int i = 1; i <= n; i++){
scanf("%d", &a[i]), pre[i] = i - 1, nxt[i] = i + 1, (i & 1 ? ord1 : ord2)[a[i]] = i;
}
const auto cmp = [](int x, int y){return a[x] < a[y];};
sort(ord1 + 1, ord1 + n + 1, cmp), sort(ord2 + 1, ord2 + n + 1, cmp);
for (int i = 1, p1 = 1, p2 = 1; i <= n - 3; i++){
int* ord = i & 1 ? ord1 : ord2, &p = i & 1 ? p1 : p2;
if (nxt[ord[p]] > n){
const int q1 = pre[ord[p]], q2 = pre[q1], q3 = pre[q2], q4 = pre[q3];
nxt[ord[p]] = q3, nxt[q2] = n + 1, nxt[q4] = q1, pre[q1] = q4, pre[q3] = ord[p];
}
const int q = nxt[ord[p]];
nxt[pre[ord[p]]] = nxt[q], pre[nxt[q]] = pre[ord[p]], nxt[q] = nxt[0], pre[nxt[0]] = q, nxt[0] = ord[p], pre[ord[p]] = 0;
printf("%d ", a[nxt[0]]), pre[nxt[nxt[0]]] = 0, nxt[0] = nxt[nxt[0]], p++;
}
for (int i = nxt[0]; i <= n; i = nxt[i]){
printf("%d ", a[i]);
}
putchar('\n');
}
return 0;
}