【Tricks,典】[ARC085F] NRE

一眼顶针,鉴定为 implement 不足,我写不出来。
先通过 Trick 转化 \(a_i = 0 \to -1,a_i = 1 \to 1\)
那么显然把 \([l, r]\) 全部摊为 1 的贡献就是 \(a_{l \to r}\)。转化为 n - 最大贡献。
然后我们可以转化以下。

\[f_i = f_j + a_r - a_{l - 1} (r_j < l) \]

\[f_i = f_j + a_r - a_{r_j} (r_j > l) \]

开两颗线段树维护即可,注意一点点 implement 就是前面啥都不放。
可能是那个 trick 没用上来,所以就没有很好地实现。
总结:可以使用 \(+1 -1\) 将区间数满足的条件转化为贡献数。

#include <bits/stdc++.h>
#define rep(i, l, r) for (int i = l; i <= r; i ++)
#define per(i, r, l) for (int i = r; i >= l; i --)
#define ckmx(x, y) x = x < y ? y : x
#define cpy(x, y, s) memcpy(x, y, sizeof(x[0]) * (s))
#define mem(x, k) memset(x, k, sizeof(x))
#define ll long long
#define lc x << 1
#define rc x << 1 | 1
// \yhx-12243/ 鱼大保佑!!
using namespace std;

const int _ = 2e5 + 5, inf = -1e9 + 5;

template <int maxn>
struct sgt {
	int tr[maxn << 2], tag[maxn << 2];
	void build (int x, int l, int r) {
		tr[x] = tag[x] = inf;
		if (l == r) return ;
		int mid = (l + r) >> 1;
		build(lc, l, mid), build(rc, mid + 1, r);
	}
	void apply (int x, int k) {	ckmx(tag[x], k), ckmx(tr[x], k); }
	void pushdown (int x) {
		apply(lc, tag[x]), apply(rc, tag[x]);
		tag[x] = inf;
	}
	void modify (int x, int l, int r, int ql, int qr, int k) {
		if (ql <= l && r <= qr) return apply(x, k), void();
		int mid = (l + r) >> 1;
		pushdown(x);
		if (ql <= mid) modify(lc, l, mid, ql, qr, k);
		if (qr > mid) modify(rc, mid + 1, r, ql, qr, k);
		tr[x] = max(tr[lc], tr[rc]);
	}
	int query (int x, int l, int r, int p) {
		if (l == r) return tr[x];
		int mid = (l + r) >> 1;
		pushdown(x);
		if (p <= mid) return query(lc, l, mid, p);
		else return query(rc, mid + 1, r, p);
	}
} ;
sgt <_> t1, t2;

struct Range {
	int l, r;
	bool operator < (const Range & x) const {
		return r < x.r || (r == x. r && l < x.l);
	}
} rn[_];

int n, q, a[_], sum, res;

int main () {
	ios :: sync_with_stdio(0);
	cin >> n;
	rep(i, 1, n) cin >> a[i], a[i] = a[i - 1] + (a[i] ? 1 : -1);
	sum = (n - a[n]) / 2, res = sum;
	cin >> q;
	rep(i, 1, q) cin >> rn[i].l >> rn[i].r;
	sort(rn + 1, rn + 1 + q);
	t1.build(1, 0, n), t2.build(1, 1, n);
	t1.modify(1, 0, n, 0, n, sum);
	rep(i, 1, q) {
		int l = rn[i].l, r = rn[i].r;
		int x = t1.query(1, 0, n, l) + a[r] - a[l - 1];
		x = max(x, t2.query(1, 1, n, l) + a[r]);
		t1.modify(1, 0, n, r + 1, n, x);
		t2.modify(1, 1, n, l, r, x - a[r]);
		res = max(res, x);
	}
	cout << n - res << endl;
	return 0;
}
posted @ 2023-08-12 15:07  Cust10  阅读(21)  评论(0)    收藏  举报