BZOJ

# 解析

$(1) a[i] < x \\ (2) a[i] = x \\ (3) a[i] > x$

# 代码

PS.以下代码自带大常数，洛谷5000+ms卡着过

#include <cstdio>
#include <cstring>
#include <iostream>
#define MAXN 100005

typedef long long LL;
struct SegmentTree {
int cnt0[MAXN << 2], cover[MAXN << 2];
void pushDown(int, int, int);
void build(int, int, int);
int query(int, int, int, int, int);
void update(int, int, int, int, int, int);
} tree;
int N, M, Q, op[MAXN], left[MAXN], right[MAXN];
int a[MAXN], b[MAXN];

bool check(int);
int main() {
std::ios::sync_with_stdio(false);
std::cin >> N >> M;
for (int i = 1; i <= N; ++i)
std::cin >> a[i];
for (int i = 1; i <= M; ++i)
std::cin >> op[i] >> left[i] >> right[i];
std::cin >> Q;
int l = 1, r = N;
while (l < r) {
int mid = (l + r) >> 1;
if (check(mid)) r = mid;
else l = mid + 1;
}
std::cout << l << std::endl;

return 0;
}
void SegmentTree::pushDown(int id, int L, int R) {
if (cover[id] == -1) return;
int mid = (L + R) >> 1;
if (cover[id]) cnt0[id << 1] = cnt0[id << 1 | 1] = 0;
else cnt0[id << 1] = mid - L + 1, cnt0[id << 1 | 1] = R - mid;
cover[id << 1] = cover[id << 1 | 1] = cover[id];
cover[id] = -1;
}
void SegmentTree::build(int id, int L, int R) {
cover[id] = -1;
if (L == R) cnt0[id] = (b[L] == 0);
else {
int mid = (L + R) >> 1;
build(id << 1, L, mid);
build(id << 1 | 1, mid + 1, R);
cnt0[id] = cnt0[id << 1] + cnt0[id << 1 | 1];
}
}
void SegmentTree::update(int id, int L, int R, int l, int r, int tp) {
if (l > r) return;
if (L >= l && R <= r) {
cover[id] = tp;
cnt0[id] = (tp ? 0 : R - L + 1);
} else {
pushDown(id, L, R);
int mid = (L + R) >> 1;
if (l <= mid) update(id << 1, L, mid, l, r, tp);
if (r > mid) update(id << 1 | 1, mid + 1, R, l, r, tp);
cnt0[id] = cnt0[id << 1] + cnt0[id << 1 | 1];
}
}
int SegmentTree::query(int id, int L, int R, int l, int r) {
if (L >= l && R <= r) return cnt0[id];
pushDown(id, L, R);
int mid = (L + R) >> 1, res = 0;
if (l <= mid) res += query(id << 1, L, mid, l, r);
if (r > mid) res += query(id << 1 | 1, mid + 1, R, l, r);
return res;
}
bool check(int m) {
for (int i = 1; i <= N; ++i)
b[i] = (a[i] > m);
tree.build(1, 1, N);
for (int i = 1; i <= M; ++i) {
int t = tree.query(1, 1, N, left[i], right[i]);
if (op[i]) tree.update(1, 1, N, right[i] - t + 1, right[i], 0), tree.update(1, 1, N, left[i], right[i] - t, 1);
else tree.update(1, 1, N, left[i], left[i] + t - 1, 0), tree.update(1, 1, N, left[i] + t, right[i], 1);
}
return tree.query(1, 1, N, Q, Q);
}

posted @ 2019-02-24 21:48  Rhein_E  阅读(80)  评论(0编辑  收藏  举报