标签:return \n amp 个数 ace 复杂 逆序 log pre
这道题目思维难度挺大的
对于一个序列,排序的本质就是消除里面的所有逆序对
考虑冒泡排序的过程,每次也是交换\(a[i]>a[i+1]\)这个逆序对
这样子交换最多有\(n^2\)次
那么我们可以用一个数据结构模拟冒泡排序交换逆序对这个过程
用一个\(set\)维护所有逆序对的位置
每次暴力删除区间内所有逆序对
再把新产生的逆序对加入\(set\)
复杂度\(O((n^2+m)\log n)\)
#include <set>
#include <cstdio>
using namespace std;
const int N = 1500 + 10;
set<int> S;
set<int>::iterator it;
int a[N], n, q, L, R;
int main() {
//freopen("miku.in", "r", stdin);
//freopen("miku.out", "w", stdout);
scanf("%d%d%d%d", &n, &q, &L, &R);
for (int i = 1; i <= n; ++ i)
scanf("%d", &a[i]);
for (int i = 1; i < n; ++ i)
if (a[i] > a[i + 1])
S.insert(i);
S.insert(n), a[n + 1] = 2e9;
while (q --) {
int l, r; scanf("%d%d", &l, &r);
for (; *(it = S.lower_bound(l)) < r; S.erase(it ++)) {
swap(a[*it], a[*it + 1]);
if(a[*it - 1] > a[*it]) S.insert(*it - 1);
if(a[*it + 1] > a[*it + 2]) S.insert(*it + 1);
}
}
for (int i = L; i <= R; ++ i)
printf("%d%c", a[i], i == R ? ‘\n‘ : ‘ ‘);
return 0;
}
标签:return \n amp 个数 ace 复杂 逆序 log pre
原文地址:https://www.cnblogs.com/brunch/p/9903888.html