牛牛与交换排序
作者:互联网
双端队列o(1)模拟区间翻转
#include <bits/stdc++.h>
#define IO ios::sync_with_stdio(0)
using namespace std;
const int N = 1e5 + 5;
bitset<N> v;
int main() {
IO;
int n; cin >> n;
vector<int> a(n + 1), p(n + 1);
deque<int> q;
for (int i = 1; i <= n; ++i) {
cin >> a[i];
p[a[i]] = i;
}
int st = 1, k = 0;
while (st <= n && a[st] == st) st++;
if (st == n + 1) cout << "yes\n1" << endl;
else {
//op记录从队头插入还是从队尾插入
int op = 1, f = 1, k = abs(st - p[st]) + 1;
for (int i = st; i <= n;) {
if (i == a[i]) {
i++;
continue;
}
//如果一个数在他第一次翻转之后仍留在原地,则该情况不合法,体现为v[i] == 1
if (v[i] || abs(i - p[i]) + 1 != k) {
f = 0;
break;
}
for (int j = i + q.size(); j < i + k; ++j) {
if (op) q.push_front(a[j]);
else q.push_back(a[j]);
v[a[j]] = 1;
}
//for (auto j = q.begin(); j != q.end(); ++j) cout << (*j) << " ";cout << endl;
if (op) {
int cnt = 0;
for (auto j = q.begin(); j != q.end(); ++j) {
if ((*j) == i) {
i++;
cnt++;
} else {
break;
}
}
while (cnt--) q.pop_front();
} else {
int cnt = 0;
//这是从队尾插入的,所以要倒着遍历
for (auto j = q.rbegin(); j != q.rend(); ++j) {
if ((*j) == i) {
i++;
cnt++;
} else {
break;
}
}
while (cnt--) q.pop_back();
}
op = !op;
}
if (q.size()) f = 0;
A:
if (f) cout << "yes\n" << k << endl;
else cout << "no\n";
}
return 0;
}
标签:cnt,牛牛,交换,++,st,int,else,排序,op 来源: https://blog.csdn.net/weixin_45563175/article/details/115584382