区间赋值的数据结构都可以骗分,在数据随机的情况下,复杂度可以保证。
时间复杂度:O(nloglogn)

struct ODT{
	struct node{
		int l, r;
		mutable LL v;
		node(int l, int r = -1, LL v = 0) : l(l), r(r), v(v) {}
		bool operator < (const node &o) const {return l < o.l;}
	};
	set<node> s;
	ODT() {s.clear();}
	auto split(int pos){
		auto it = s.lower_bound(node(pos));
		if (it != s.end() && it -> l == pos) return it;
		it -- ;
		int l = it -> l, r = it -> r;
		LL 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, LL x){
		auto itr = split(r + 1), itl = split(l);
		s.erase(itl, itr);
		s.insert(node(l, r, x));
	}
	void add(int l, int r, LL x){
		auto itr = split(r + 1), itl = split(l);
		for (auto it = itl; it != itr; it ++ ){
			it -> v += x;
		}
	}
	LL kth(int l, int r, int k){
		vector<pair<LL, int>> a;
		auto itr = split(r + 1), itl = split(l);
		for (auto it = itl; it != itr; it ++ ){
			a.push_back(pair<LL, int>(it -> v, it -> r - it -> l + 1));
		}
		sort(a.begin(), a.end());
		for (auto [val, len] : a){
			k -= len;
			if (k <= 0) return val;
		}
	}
	LL quickpow(LL a, int b, int mod){
		a %= mod;
		LL ans = 1;
		while (b){
			if (b & 1){
				ans = ans * a % mod;
			}
			b >>= 1;
			a = a * a % mod;
		}
		return ans;
	}
	LL powersum(int l, int r, int x, int mod){
		auto itr = split(r + 1), itl = split(l);
		LL ans = 0;
		for (auto it = itl; it != itr; it ++ ){
			ans = (ans + quickpow(it -> v, x, mod) * (it -> r - it -> l + 1) % mod) % mod;
		}
		return ans;
	}
};
posted on 2023-05-23 14:25  Hamine  阅读(65)  评论(0编辑  收藏  举报