[题目链接]
https://www.lydsy.com/JudgeOnline/problem.php?id=4552
[算法]
首先 , 二分答案x , 将比x小的数看作1,比x大的数看作0
然后用线段树检验即可
时间复杂度 : O(MlogN^2)
[代码]
#include<bits/stdc++.h> using namespace std; const int MAXN = 1e5 + 10; int n , m , q; int a[MAXN],b[MAXN]; struct Que { int op , l , r; } que[MAXN]; struct Node { int l , r; int tag , cnt; } Tree[MAXN << 2]; template <typename T> inline void chkmax(T &x,T y) { x = max(x,y); } template <typename T> inline void chkmin(T &x,T y) { x = min(x,y); } template <typename T> inline void read(T &x) { T f = 1; x = 0; char c = getchar(); for (; !isdigit(c); c = getchar()) if (c == '-') f = -f; for (; isdigit(c); c = getchar()) x = (x << 3) + (x << 1) + c - '0'; x *= f; } inline void update(int index) { Tree[index].cnt = Tree[index << 1].cnt + Tree[index << 1 | 1].cnt; } inline void build(int index,int l,int r) { Tree[index].l = l; Tree[index].r = r; Tree[index].tag = -1; if (l == r) { Tree[index].cnt = b[l]; return; } int mid = (l + r) >> 1; build(index << 1,l,mid); build(index << 1 | 1,mid + 1,r); update(index); } inline void pushdown(int index) { int l = Tree[index].l , r = Tree[index].r , mid = (l + r) >> 1; if (Tree[index].tag != -1) { if (Tree[index].tag) { Tree[index << 1].cnt = mid - l + 1; Tree[index << 1 | 1].cnt = r - mid; Tree[index << 1].tag = Tree[index << 1 | 1].tag = 1; } else { Tree[index << 1].cnt = Tree[index << 1 | 1].cnt = 0; Tree[index << 1].tag = Tree[index << 1 | 1].tag = 0; } Tree[index].tag = -1; } } inline void modify(int index,int l,int r,int value) { if (l > r) return; if (Tree[index].l == l && Tree[index].r == r) { if (value == 1) Tree[index].cnt = Tree[index].r - Tree[index].l + 1; else Tree[index].cnt = 0; Tree[index].tag = value; return; } pushdown(index); int mid = (Tree[index].l + Tree[index].r) >> 1; if (mid >= r) modify(index << 1,l,r,value); else if (mid + 1 <= l) modify(index << 1 | 1,l,r,value); else { modify(index << 1,l,mid,value); modify(index << 1 | 1,mid + 1,r,value); } update(index); } inline int query(int index,int l,int r) { if (Tree[index].l == l && Tree[index].r == r) return Tree[index].cnt; pushdown(index); int mid = (Tree[index].l + Tree[index].r) >> 1; if (mid >= r) return query(index << 1,l,r); else if (mid + 1 <= l) return query(index << 1 | 1,l,r); else return query(index << 1,l,mid) + query(index << 1 | 1,mid + 1,r); } inline bool check(int x) { for (int i = 1; i <= n; i++) b[i] = (a[i] <= x); build(1,1,n); for (int i = 1; i <= m; i++) { if (que[i].op == 0) { int cnt = query(1,que[i].l,que[i].r); modify(1,que[i].l,que[i].l + cnt - 1,1); modify(1,que[i].l + cnt,que[i].r,0); } else { int cnt = query(1,que[i].l,que[i].r); modify(1,que[i].l,que[i].r - cnt,0); modify(1,que[i].r - cnt + 1,que[i].r,1); } } return query(1,q,q) == 1; } int main() { read(n); read(m); for (int i = 1; i <= n; i++) read(a[i]); for (int i = 1; i <= m; i++) { read(que[i].op); read(que[i].l); read(que[i].r); } read(q); int l = 1 , r = n , ans; while (l <= r) { int mid = (l + r) >> 1; if (check(mid)) { ans = mid; r = mid - 1; } else l = mid + 1; } printf("%d ",ans); return 0; }