Loading

CF2096F Wonderful Impostors(线段树,*)

CF2096F Wonderful Impostors

用 AIIDE 写的,感觉还行。我的感觉还是很准的,必须求出 mnl[r]。没想到要用如此暴力的方法判断添加一个 0 后前面的 1 该不该删。暴力美学。下次自信地认为自己能做出所有题的时候,必须先自信地认为自己能写出符合常识的情况下能做到一切功能的数据结构。

Code

#include <bits/stdc++.h>

using namespace std;
using ll = long long;
#define sz(a) (int)(a).size()
#define all(a) (a).begin(), (a).end()

template<typename A>
string to_string(A v) {
	string s = "{";
	for (auto x : v) {
		if (sz(s) > 1) {
			s += ", ";
		}
		s += to_string(x);
	}
	return s += "}";
}

void debug_out() {
	cerr << "\n";
}

template<typename T, typename... U>
void debug_out(const T& x, const U&... args) {
	cerr << " " << to_string(x);
	debug_out(args...);
}

#define debug(...) cerr << "[" << #__VA_ARGS__ << "]:", debug_out(__VA_ARGS__)

struct divt {
	struct node {
		int x, l, r;

		node(): x(0), l(-1), r(-1) {}
		node(int x, int l, int r): x(x), l(l), r(r) {}
	};

	node merge(node u, node v) {
		if (u.x != v.x) {
			return u.x < v.x ? u : v;
		}
		return node(u.x, u.l, v.r);
	}

	vector<node> f;
	vector<int> g;

	void pushtag(int u, int x) {
		f[u].x += x;
		g[u] += x;
	}

	void pushdown(int u) {
		if (g[u]) {
			pushtag(u * 2, g[u]);
			pushtag(u * 2 + 1, g[u]);
			g[u] = 0;
		}
	}
	
	void build(int u, int l, int r) {
		if (r - l == 1) {
			f[u] = node(0, l, l);
			return;
		}
		int m = (l + r) / 2;
		build(u * 2, l, m);
		build(u * 2 + 1, m, r);
		f[u] = merge(f[u * 2], f[u * 2 + 1]);
	}

	divt(int n): f(n * 4), g(n * 4, 0) {
		build(1, 0, n);
	}

	int lefmin(int i, int u, int l, int r) {
		if (f[u].x > 0) {
			return -1;
		}
		if (r - l == 1) {
			return l;
		}
		pushdown(u);
		int m = (l + r) / 2;
		if (i < m) {
			return lefmin(i, u * 2, l, m);
		}
		int res = lefmin(i, u * 2 + 1, m, r);
		if (res == -1 && f[u * 2].x <= 0) {
			res = f[u * 2].r;
		}
		return res;
	}

	int rigmax(int i, int u, int l, int r) {
		if (f[u].x > 0) {
			return -1;
		}
		if (r - l == 1) {
			return l;
		}
		pushdown(u);
		int m = (l + r) / 2;
		if (i >= m) {
			return rigmax(i, u * 2 + 1, m, r);
		}
		int res = rigmax(i, u * 2, l, m);
		if (res == -1 && f[u * 2 + 1].x <= 0) {
			res = f[u * 2 + 1].l;
		}
		return res;
	}

	void add(int x, int y, int v, int u, int l, int r) {
		// if (u == 1) {
		// 	debug(x, y, v);
		// }
		if (x >= r || y <= l) {
			return;
		}
		if (x <= l && r <= y) {
			pushtag(u, v);
			return;
		}
		pushdown(u);
		int m = (l + r) / 2;
		add(x, y, v, u * 2, l, m);
		add(x, y, v, u * 2 + 1, m, r);
		f[u] = merge(f[u * 2], f[u * 2 + 1]);
	}

	bool query(int x, int y, int u, int l, int r) {
		if (x >= r || y <= l) {
			return false;
		}
		if (x <= l && r <= y) {
			return f[u].x <= 0;
		}
		pushdown(u);
		int m = (l + r) / 2;
		return query(x, y, u * 2, l, m) || query(x, y, u * 2 + 1, m, r);
	}
};

struct divq {
	vector<pair<int, int>> f;

	divq(int n): f(n * 4, make_pair(-1, -1)) {}

	void pushup(int u) {
		f[u] = max(f[u * 2], f[u * 2 + 1]);
	}

	void modify(int x, pair<int, int> v, int u, int l, int r) {
		if (r - l == 1) {
			f[u] = v;
			return;
		}
		int m = (l + r) / 2;
		if (x < m) {
			modify(x, v, u * 2, l, m);
		} else {
			modify(x, v, u * 2 + 1, m, r);
		}
		pushup(u);
	}

	pair<int, int> query(int y, int u, int l, int r) {
		if (y <= l) {
			return make_pair(-1, -1);
		}
		if (r <= y) {
			return f[u];
		}
		int m = (l + r) / 2;
		return max(query(y, u * 2, l, m), query(y, u * 2 + 1, m, r));
	}
};

int main() {
	// freopen("F.in", "r", stdin);
	ios::sync_with_stdio(false);
	cin.tie(0);
	int tt;
	cin >> tt;
	while (tt--) {
		int n, m;
		cin >> n >> m;
		vector<int> X(m), A(m), B(m);
		for (int i = 0; i < m; i++) {
			cin >> X[i] >> A[i] >> B[i], --A[i];
		}
		divt T(n);
		divq Q(n);
		vector<set<pair<int, int>>> S(n);
		vector mxs(n, make_pair(-1, -1));
		auto add = [&](int x, int y, int i) {
			--y;
			S[y].insert(make_pair(x, i));
			if (*S[y].rbegin() > mxs[y]) {
				mxs[y] = *S[y].rbegin();
				Q.modify(y, mxs[y], 1, 0, n);
			}
		};
		auto del = [&](int x, int y, int i) {
			--y;
			S[y].erase(make_pair(x, i));
			if (S[y].empty()) {
				mxs[y] = make_pair(-1, -1);
				Q.modify(y, mxs[y], 1, 0, n);
			} else if (*S[y].rbegin() < mxs[y]) {
				mxs[y] = *S[y].rbegin();
				Q.modify(y, mxs[y], 1, 0, n);
			}
		};
		vector mnl(m + 1, -1);
		int cur = 0;
		for (int i = 0; i < m; i++) {
			if (X[i] == 0) {
				T.add(A[i], B[i], 1, 1, 0, n);
				while (cur < i) {
					int L = A[i] == 0 ? 0 : T.lefmin(A[i] - 1, 1, 0, n) + 1;
					int R = B[i] == n ? n : T.rigmax(B[i], 1, 0, n);
					if (R == -1) {
						R = n;
					}
					auto [x, j] = Q.query(R, 1, 0, n);
					// if (i == 8) {
					// 	debug(L, R, x, j);
					// }
					if (x < L) {
						break;
					}
					if (X[cur] == 1) {
						del(A[cur], B[cur], cur);
					} else {
						T.add(A[cur], B[cur], -1, 1, 0, n);
					}
					cur++;
				}
				mnl[i + 1] = cur;
			} else {
				// debug((int)T.query(A[i], B[i], 1, 0, n));
				while (cur < i && !T.query(A[i], B[i], 1, 0, n)) {
					while (cur < i && X[cur] == 1) {
						del(A[cur], B[cur], cur);
						cur++;
					}
					T.add(A[cur], B[cur], -1, 1, 0, n);
					cur++;
				}
				add(A[i], B[i], i);
				mnl[i + 1] = cur;
			}
			// debug(i, mnl[i + 1]);
		}
		int q;
		cin >> q;
		while (q--) {
			int l, r;
			cin >> l >> r, --l;
			cout << (mnl[r] <= l ? "YES" : "NO") << '\n';
		}
	}
}
posted @ 2025-04-26 11:37  Pizza1123  阅读(34)  评论(0)    收藏  举报