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.
|
|
|
|
#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;
|
|
|
|
|
}
|