Description
给出一个11到的全排列,现对于这个全排列进行mm次局部排序操作。
- 表示将区间[l,r][l,r]的数字升序排序。
- (1,l,r)(1,l,r)表示将区间[l,r][l,r]的数字降序排序。
排序后询问第qq位置上的数字。
Solution
考虑每次只询问一个位置上的数字,可以二分数字。把的值置为00,的值置为00。
只有的排序很简单,每次统计有多少0,10,1,然后做区间覆盖即可。
根据qq位置上的值确定答案与当前二分值的关系。
#include <bits/stdc++.h> using namespace std; const int maxn = 1005; int n, m, q; int a[maxn], op[maxn], l[maxn], r[maxn]; inline int gi() { char c = getchar(); while (c < '0' || c > '9') c = getchar(); int sum = 0; while ('0' <= c && c <= '9') sum = sum * 10 + c - 48, c = getchar(); return sum; } #define lch (s << 1) #define rch (s << 1 | 1) #define mid ((l + r) >> 1) int sum[maxn * 4], lazy[maxn * 4]; void build(int s, int l, int r, int x) { lazy[s] = -1; if (l == r) { sum[s] = a[l] > x; return ; } build(lch, l, mid, x); build(rch, mid + 1, r, x); sum[s] = sum[lch] + sum[rch]; } int query(int s, int l, int r, int x, int y) { if (x <= l && r <= y) return sum[s]; if (~lazy[s]) { sum[lch] = (mid - l + 1) * lazy[s]; lazy[lch] = lazy[s]; sum[rch] = (r - mid) * lazy[s]; lazy[rch] = lazy[s]; lazy[s] = -1; } int res = 0; if (x <= mid) res += query(lch, l, mid, x, y); if (mid < y) res += query(rch, mid + 1, r, x, y); return res; } void cover(int s, int l, int r, int x, int y, int v) { if (x <= l && r <= y) { sum[s] = (r - l + 1) * v; lazy[s] = v; return; } if (~lazy[s]) { sum[lch] = (mid - l + 1) * lazy[s]; lazy[lch] = lazy[s]; sum[rch] = (r - mid) * lazy[s]; lazy[rch] = lazy[s]; lazy[s] = -1; } if (x <= mid) cover(lch, l, mid, x, y, v); if (mid < y) cover(rch, mid + 1, r, x, y, v); sum[s] = sum[lch] + sum[rch]; } bool judge(int x) { build(1, 1, n, x); for (int i = 1, sum; i <= m; ++i) { if (!op[i]) { sum = r[i] - l[i] + 1 - query(1, 1, n, l[i], r[i]); if (sum) cover(1, 1, n, l[i], l[i] + sum - 1, 0); if (sum < r[i] - l[i] + 1) cover(1, 1, n, l[i] + sum, r[i], 1); } else { sum = query(1, 1, n, l[i], r[i]); if (sum) cover(1, 1, n, l[i], l[i] + sum - 1, 1); if (sum < r[i] - l[i] + 1) cover(1, 1, n, l[i] + sum, r[i], 0); } } return query(1, 1, n, q, q); } int main() { freopen("sort.in", "r", stdin); freopen("sort.out", "w", stdout); n = gi(); m = gi(); for (int i = 1; i <= n; ++i) a[i] = gi(); for (int i = 1; i <= m; ++i) op[i] = gi(), l[i] = gi(), r[i] = gi(); q = gi(); int l = 1, r = n; while (l < r) { if (judge(mid)) l = mid + 1; else r = mid; } printf("%d\n", l); return 0; }