You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

61 lines
2.1 KiB

2 years ago
#pragma GCC optimize(2) // 累了就吸点氧吧~
#include <bits/stdc++.h>
using namespace std;
const int N = 200010;
struct Node { // 块
int st, ed, th;
};
int n, a[N];
queue<Node> q1, q2;
bool used[N]; // 记录是否被取出
int main() {
// 加快读入
ios::sync_with_stdio(false), cin.tie(0);
cin >> n;
memset(a, -1, sizeof a);
for (int i = 1; i <= n; i++) cin >> a[i];
// 很经典的代码
for (int i = 2, x = 1; i <= n; i++)
if (a[i] != a[i + 1])
q1.push({x, i, a[i]}), x = i + 1; // 把连续一段相同的元素合成一个块
// 取没拉倒
while (n) {
while (q1.size()) { // 有块存在
Node k = q1.front(); // k这个块
q1.pop();
// 1111 00 1111 :取两轮后第1块和第3块就会连上
while (used[k.st]) k.st++; // 跳过块中已取过的水果
if (k.st > k.ed) continue; // 取没了,这个块就放过,看看下一个块吧
printf("%d ", k.st); // 如果没有取没,那就取这个号的水果
n--; // 取走一个水果
used[k.st] = 1; // 标识已取出
k.st++; // 不是最后一个,取完后块的开始位置
if (k.st > k.ed) continue; // 取没了,这个块就放过,看看下一个块吧
q2.push(k); // 先将缩减的小块存到 q2 里,因为可能会有些区间连上了,需要进行合并
}
puts("");
// 1111 00 1111 :取两轮后第1块和第3块就会连上
// 完成合并任务
while (q2.size()) {
Node k = q2.front();
q2.pop();
while (q2.size()) {
Node x = q2.front();
if (x.th == k.th) { // 能合并就合并
k.ed = x.ed;
q2.pop();
} else
break;
}
q1.push(k); // 丢回 q1 里
}
}
return 0;
}