LuoguP1276校门外的树(增强版)

题目链接

  读题可以发现,我们要实现区间整体变成\(0\),和区间内非\(0\)的位置建上一颗树。那么这个时候我们看到有区间推平操作就可以想到神奇的珂朵莉树(\(ODT\)),那么这个时候我们就要考虑将树木和树苗区分开,我们可以假定树苗是\(1\),树木的值是\(2\)。那么在砍树的时候直接推平整个区间,但是在推平的过程中要用\(res\)记录下有多少颗树苗被砍掉了;在植树的时候,我们不可以采用推平的操作,因为所选中的区间可能会有位置原来种有树木,所以我们要循环这个区间,将这个区间\(val = 0\)的位置变成\(1\)

i64 res;

struct Tree {
	struct Node {
		int l, r;
		mutable i64 val;

		Node(int l, int r = 0, i64 val = 0) : l(l), r(r), val(val) {}

		bool operator <(const Node& lhs) const {
			return this -> l < lhs.l;
		}
	};
	std::set<Node> s;

	std::set<Node>::iterator split(int pos) {
		std::set<Node>::iterator it = s.lower_bound(Node(pos));
		if (it -> l == pos && it != s.end()) return it;
		-- it;
		if (it -> r < pos) return s.end();

		i64 l = it -> l, r = it -> r, val = it -> val;
		s.erase(it);
		s.insert(Node(l, pos - 1, val));
		return s.insert(Node(pos, r, val)).first;
	}

	void assaign(int l, int r, i64 x) {
		auto itr = split(r + 1), itl = split(l);
		for (auto it = itl; it != itr; ++ it) 
			if (it -> val == 2) 
				res += it -> r - it -> l + 1; 
		s.erase(itl, itr);
		s.insert(Node(l, r, x));
	}

	void plant(int l, int r) {
		auto itr = split(r + 1), itl = split(l);
		for (auto it = itl; it != itr; ++ it) 
			if (it -> val == 0) 
				it -> val += 2;
	}

	void add(int l, int r, i64 x) {
		auto itr = split(r + 1), itl = split(l);
		for (auto it = itl; it != itr; ++ it) 
			if (it -> val == 0) 
				it -> val += x;
	}

	i64 query(int l, int r) {
		i64 ans = 0;
		auto itr = split(r + 1), itl = split(l);
		for (auto it = itl; it != itr; it ++ ) 
			ans += (it -> val == 2 ? 1 : 0) * (it -> r - it -> l + 1);
		return ans;
	}
};

int main() {
	std::cin.tie(nullptr)->sync_with_stdio(false);

	int n, m;
	std::cin >> n >> m;
	Tree ODT;
	ODT.s.insert(Tree::Node(0, n, 1));
	for (int i = 0; i < m; i ++ ) {
		int x, l, r;
		std::cin >> x >> l >> r;
		if (x == 0) ODT.assaign(l, r, x);
		else {
			ODT.plant(l, r);
		}
	}

	std::cout << ODT.query(0, n) << "\n" << res << "\n";

	return 0 ^ 0;
}
posted @ 2022-07-29 22:44  浅渊  阅读(75)  评论(0)    收藏  举报