提出 #70631282


ソースコード 拡げる

#include <bits/stdc++.h>
#include <atcoder/all>
using namespace std;
using namespace atcoder;
//using mint = modint1000000007;
//const int mod = 1000000007;
//using mint = modint998244353;
//const int mod = 998244353;
const int INF = 1e9;
//const long long LINF = 1e18;
#define rep(i, n) for (int i = 0; i < (n); ++i)
#define rep2(i,l,r)for(int i=(l);i<(r);++i)
#define rrep(i, n) for (int i = (n) - 1; i >= 0; --i)
#define rrep2(i,l,r)for(int i=(r) - 1;i>=(l);--i)
#define all(x) (x).begin(),(x).end()
#define allR(x) (x).rbegin(),(x).rend()
#define P pair<int,int>
template<typename A, typename B> inline bool chmax(A & a, const B & b) { if (a < b) { a = b; return true; } return false; }
template<typename A, typename B> inline bool chmin(A & a, const B & b) { if (a > b) { a = b; return true; } return false; }
#include <set>
#include <iostream> 

#include <set>
#include <iostream> 

template<typename T>
struct RangeSet {
	// ReadMe:閉区間なことに注意
	// member
	std::set<std::pair<T, T>>st;
	T TINF;
	// constructor
	RangeSet(T lim) {
		TINF = lim + 1;
		st.emplace(-TINF, -TINF);
		st.emplace(TINF, TINF);
	}
	// cover check
	bool IsCovered(T l, T r) {
		auto ite = prev(st.lower_bound({ l + 1,l + 1 }));
		return ((ite->first <= l) && (r <= ite->second));
	}
	bool IsCovered(T x) { return IsCovered(x, x); }
	// get by covered
	std::pair<T, T> ByCovered(T l, T r) {
		auto ite = prev(st.lower_bound({ l + 1,l + 1 }));
		if ((ite->first <= l) && (r <= ite->second)) return *ite;
		return { -TINF, -TINF };
	}
	std::pair<T, T> ByCovered(T  x) { return ByCovered(x, x); }
	// getFront
	std::pair<T, T>getFront() {
		auto itr = st.begin();
		itr++;
		return *itr;
	}
	// getBack
	std::pair<T, T>getBack() {
		auto itr = st.end();
		itr--;
		itr--;
		return *itr;
	}
	// insert
	T Insert(T l, T r, const std::function<void(int, int)> &insert, const std::function<void(int, int)> &erase) {
		//insertでmargeしないver
		//st.emplace(l, r);
		//return 0;
		T sumErase = T(0);
		auto ite = prev(st.lower_bound({ l + 1,l + 1 }));
		// no need merge
		if (IsCovered(l, r))return sumErase;
		// first merge pos
		if ((ite->first <= l) && (l <= (ite->second + 1))) {
			l = ite->first;
			sumErase += ite->second - ite->first + 1;
			erase(ite->first, ite->second);
			ite = st.erase(ite);
		}
		else ite = next(ite);
		// merge
		while (r > ite->second) {
			sumErase += ite->second - ite->first + 1;
			erase(ite->first, ite->second);
			ite = st.erase(ite);
		}
		if (((ite->first - 1) <= r) && (r <= ite->second)) {
			r = ite->second;
			sumErase += ite->second - ite->first + 1;
			erase(ite->first, ite->second);
			st.erase(ite);
		}
		insert(l, r);
		st.emplace(l, r);
		return (r - l + 1) - sumErase;
	}
	//T Insert(T x) { return Insert(x, x); }
	// erase
	T Erase(T l, T r, const std::function<void(int, int)> &insert, const std::function<void(int, int)> &erase) {
		T ret = T(0);
		auto get = ByCovered(l, r);
		if ((-TINF) != get.first) {
			erase(get.first, get.second);
			st.erase(get);
			if (get.first != l) {
				insert(get.first, l - 1);
				st.emplace(get.first, l - 1);
			}
			if (get.second != r) {
				insert(r + 1, get.second);
				st.emplace(r + 1, get.second);
			}
			ret += r - l + 1;
			return ret;
		}
		auto ite = prev(st.lower_bound({ l + 1,l + 1 }));
		// first erase
		if ((ite->first <= l) && (l <= ite->second)) {
			ret += ite->second - l + 1;
			if (ite->first != l) {
				insert(ite->first, l - 1);
				st.emplace(ite->first, l - 1);
			}
			erase(ite->first, ite->second);
			ite = st.erase(ite);
		}
		else ite = next(ite);
		// erase
		while (ite->second <= r) {
			ret += ite->second - ite->first + 1;
			erase(ite->first, ite->second);
			ite = st.erase(ite);
		}
		// last
		if ((ite->first <= r) && (r <= ite->second)) {
			ret += r - ite->first + 1;
			if (ite->second != r) {
				insert(r + 1, ite->second);
				st.emplace(r + 1, ite->second);
			}
			erase(ite->first, ite->second);
			st.erase(ite);
		}
		return ret;
	}
	//T Erase(T x) { return Erase(x, x); }
	// range count
	int size() { return st.size() - 2; }
	// mex
	T Mex(T x = 0) {
		if (!IsCovered(x)) return x;
		auto ite = prev(st.lower_bound({ x + 1, x + 1 }));
		return ite->second + 1;
	}
	// debug
	void Debug() {
		for (auto[l, r] : st)std::cout << l << " " << r << std::endl;
	}
};
namespace RangeAddRangeMax {
	// 区間加算・区間最大値取得(個数付き)
	using S = std::pair<long long, int>;
	using F = long long;
	//const S INF = {8e18;
	S op(S a, S b) {
		if (a.first > b.first)return a;
		else if (a.first < b.first)return b;
		return { a.first,a.second + b.second };
	}
	S e() { return { -8e18,0 }; }
	S mapping(F f, S x) { return { x.first + f,x.second }; }
	F composition(F f, F g) { return f + g; }
	F id() { return 0; }
	using lazy_segtree = atcoder::lazy_segtree<S, op, e, F, mapping, composition, id>;
}
int main() {
	std::ios::sync_with_stdio(false);
	std::cin.tie(nullptr);
	int n, q; cin >> n >> q;
	RangeAddRangeMax::lazy_segtree seg(n);
	rep(i, n)seg.set(i, { 0,1 });

	vector<RangeSet<int>> rst(60, RangeSet<int>(INF));
	auto add = [&](int l, int r) -> void {
		//cout << l << " " << r << endl;
		seg.apply(l, r + 1, 1);
	};
	auto del = [&](int l, int r) -> void {
		//cout << l << "_" << r << endl;
		seg.apply(l, r + 1, -1);
	};
	while (q--) {
		int t, l, r; cin >> t >> l >> r;
		l--;
		if (t == 1) {
			int x; cin >> x;
			x--;
			rst[x].Insert(l, r - 1, add, del);
		}
		else if (t == 2) {
			int x; cin >> x;
			x--;
			rst[x].Erase(l, r - 1, add, del);
		}
		else {
			auto val = seg.prod(l, r);
			cout << val.first << " " << val.second << endl;
		}
		//rep(i, n) {
		//	cout << seg.get(i).first << "_";
		//}cout << endl;
	}
	return 0;
}

提出情報

提出日時
問題 G - Range Set Modifying Query
ユーザ kwm_t
言語 C++23 (GCC 15.2.0)
得点 625
コード長 5919 Byte
結果 AC
実行時間 395 ms
メモリ 29792 KiB

ジャッジ結果

セット名 Sample All
得点 / 配点 0 / 0 625 / 625
結果
AC × 1
AC × 32
セット名 テストケース
Sample sample_01.txt
All min_1.txt, min_2.txt, random_01.txt, random_02.txt, random_03.txt, random_04.txt, random_05.txt, random_06.txt, random_07.txt, random_08.txt, random_09.txt, random_10.txt, random_11.txt, random_12.txt, random_13.txt, random_14.txt, random_15.txt, random_16.txt, random_17.txt, random_18.txt, random_19.txt, random_20.txt, random_21.txt, random_22.txt, random_23.txt, random_24.txt, random_25.txt, random_26.txt, random_27.txt, random_28.txt, random_29.txt, sample_01.txt
ケース名 結果 実行時間 メモリ
min_1.txt AC 1 ms 3612 KiB
min_2.txt AC 1 ms 3496 KiB
random_01.txt AC 1 ms 3528 KiB
random_02.txt AC 1 ms 3604 KiB
random_03.txt AC 2 ms 3612 KiB
random_04.txt AC 2 ms 3656 KiB
random_05.txt AC 2 ms 3712 KiB
random_06.txt AC 2 ms 3688 KiB
random_07.txt AC 3 ms 3832 KiB
random_08.txt AC 287 ms 28536 KiB
random_09.txt AC 212 ms 4980 KiB
random_10.txt AC 77 ms 28404 KiB
random_11.txt AC 172 ms 16856 KiB
random_12.txt AC 395 ms 28392 KiB
random_13.txt AC 367 ms 17256 KiB
random_14.txt AC 284 ms 28392 KiB
random_15.txt AC 204 ms 16872 KiB
random_16.txt AC 283 ms 28380 KiB
random_17.txt AC 218 ms 5112 KiB
random_18.txt AC 278 ms 28404 KiB
random_19.txt AC 80 ms 9560 KiB
random_20.txt AC 395 ms 28532 KiB
random_21.txt AC 341 ms 16032 KiB
random_22.txt AC 381 ms 28532 KiB
random_23.txt AC 250 ms 28532 KiB
random_24.txt AC 292 ms 28396 KiB
random_25.txt AC 377 ms 28452 KiB
random_26.txt AC 266 ms 28380 KiB
random_27.txt AC 311 ms 28512 KiB
random_28.txt AC 297 ms 28376 KiB
random_29.txt AC 295 ms 29792 KiB
sample_01.txt AC 2 ms 3588 KiB