ODT

CF1638E Colorful Operations

从这个题目开始,提取关键词:颜色、操作序列,我们很快就能想到建立颜色个数个线段树,但当颜色个数比较大时,我们不可能建立那么多线段树,考虑到区间覆盖,我们可以思考的是,是否可以用一个规则来概括整个区间,那么在这里,我们就认为整个区间都是一个颜色。

ODT

我们通过用平衡树来描述区间,可以用 \(map<int, int>\) 来表示区间左端点和区间中颜色,在操作中我们可以像 FHQ 那样将区间分裂出来进行处理。

因为思路比较简单,所以直接上代码,时间复杂度我不会证

auto split(int p) {
	auto it = prev(odt.upper_bound(p));
	return odt.insert(it, make_pair(p, it->second));
}

void assign(int l, int r, int c) {
	split(l), split(r + 1);
	for (auto it = odt.find(l);it->first != r + 1; it = odt.erase(it)) {
		modify(it->first, tag[it->second]);
		modify(next(it)->first, -tag[it->second]);
	}
	odt[l] = c, modify(l, -tag[c]), modify(r + 1, tag[c]);
}

思路

我们考虑对于这道题目,有三种操作

  1. 区间颜色改变,直接对应 \(assign\) 操作
  2. 对于有特定颜色的节点进行加减操作
  3. 单点查询

对于 2 操作,由于特定颜色节点不一定抱团,所以我们使用懒标记,不过懒标记在什么时候需要改变呢?

在 1 操作中,会将结构进行改变,在改变过程中,需将标记下放到每一个区间中,这里需要用区间修改,用树状数组,在颜色修改完毕后,由于改后颜色在过去的 tag 不应该影响到现在的所以需要减掉以抵消,在树状数组上减即可

code

#include <iostream>
#include <map>
#define int long long
#define lb(x) (x & (-x))

using namespace std;

const int MaxN = 1e6 + 10;

int tag[MaxN], d[MaxN], n, q;
map<int, int> odt;
string op;

void modify(int k, int x) {
	for (k; k <= n; d[k] += x, k += lb(k)) {
	}
}

int query(int k, int res = 0) {
	for (k; k; res += d[k], k -= lb(k)) {
	}
	return res;
}

auto split(int p) {
	auto it = prev(odt.upper_bound(p));
	return odt.insert(it, make_pair(p, it->second));
}

void assign(int l, int r, int c) {
	split(l), split(r + 1);
	for (auto it = odt.find(l);it->first != r + 1; it = odt.erase(it)) {
		modify(it->first, tag[it->second]);
		modify(next(it)->first, -tag[it->second]);
	}
	odt[l] = c, modify(l, -tag[c]), modify(r + 1, tag[c]);
}

int get(int c) {
	auto it = prev(odt.upper_bound(c));
	return it->second;
}

signed main() {
	cin >> n >> q;
	odt[0] = -1, odt[n + 1] = -1, odt[1] = 1;
	for (int l, r, c, x; q; q--) {
		cin >> op;
		if (op == "Color") {
			cin >> l >> r >> c;
			assign(l, r, c);
		} else if (op == "Add") {
			cin >> c >> x;
			tag[c] += x;
		} else {
			cin >> x;
			cout << query(x) + tag[get(x)] << endl;
		}
	} 	 
	return 0;
}
posted @ 2025-07-23 20:58  yabnto  阅读(14)  评论(0)    收藏  举报