[CF915E]Physical Education Lessons

题目大意:有$n$个点,原来都是$1$,$m$次区间修改,将$[l,r]$中所有元素改为一个值,问每次操作后$n$个点的和。$n\leqslant10^9,m\leqslant3\times10^5$

题解:动态开点线段树,但是因为刚学习$ODT$,就拿这道题练手,直接相同元素直接修改,在修改的同时更新答案。

卡点:

 

C++ Code:

#include <cstdio>
#include <algorithm>
#include <cstring>
#include <set>
#include <iostream>

int n, q, ans;

namespace ODT {
	struct node {
		int l, r;
		mutable int v;
		inline bool operator < (const node &rhs) const {
			return l < rhs.l;
		}
	} ;
	std::set<node> s;
	typedef std::set<node>::iterator SIT;
	SIT split(int pos) {
		SIT it = s.lower_bound((node) { pos, 0, 0 });
		if (it != s.end() && it -> l == pos) return it;
		--it; const int l = it -> l, r = it -> r, v = it -> v;
		s.erase(it), s.insert((node) { l, pos - 1, v });
		return s.insert((node) { pos, r, v}).first;
	}
	void assign(int l, int r, int v) {
		SIT R = split(r + 1), L = split(l);
		for (SIT it = L; it != R; ++it)
			ans -= it -> v * (it -> r - it -> l + 1);
		s.erase(L, R), s.insert((node) { l, r, v });
		ans += v * (r - l + 1);
	}
}

int main() {
	std::ios::sync_with_stdio(false), std::cin.tie(0), std::cout.tie(0);
	std::cin >> n >> q; ans = n;
	ODT::s.insert((ODT::node) { 1, n, 1 });
	while (q --> 0) {
		static int l, r, x;
		std::cin >> l >> r >> x; --x;
		ODT::assign(l, r, x);
		std::cout << ans << '\n';
	}
	return 0;
}

  

转载于:https://www.cnblogs.com/Memory-of-winter/p/11332986.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值