专栏文章
题解:CF2101B Quartet Swapping
CF2101B题解参与者 1已保存评论 0
文章操作
快速查看文章及其快照的属性,并进行相关操作。
- 当前评论
- 0 条
- 当前快照
- 1 份
- 快照标识符
- @minzws80
- 此快照首次捕获于
- 2025/12/02 11:05 3 个月前
- 此快照最后确认于
- 2025/12/02 11:05 3 个月前
首先我们注意到奇数位和偶数位是独立的,将其分开考虑。我们考虑贪心地从前向后要求每一位最小,也就是从小到大枚举 ,将与第 位奇偶相同的最小值移动到第 位上,然后将其删去。
令 为当前剩余的数字数量,最小值在第 位上。我们发现如果 ,直接向前交换即可;但是 较为麻烦,我们考量这样一个示例
我们发现对于 进行一次操作即可,这样可以将 从 调整到 。
使用链表维护 交换、删除。一共有 次找最大值的操作,共 次交换,时间复杂度 。
Code:
CPP#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;
}
相关推荐
评论
共 0 条评论,欢迎与作者交流。
正在加载评论...