chenfy27的刷题记录

导航

luoguP1558 色板游戏

有编号为1~T的T种颜色和一块长为L的色板,每块色板只有一个颜色,最初均为颜色1,有O次操作:

  • C x y z,将区间[x,y]的色板涂成颜色z。
  • P x y,询问区间[x,y]有多少种不同的颜色。

范围:1<=L<=1e5, 1<=T<=30, 1<=O<=1e5。

分析:线段树维护区间内有哪些颜色,因为颜色种数少,可以用状压或者bitset。

#include <bits/stdc++.h>
using llong = long long;

// LazySegmentTree模板...

struct Tag {
	int c;
	Tag(int C=0):c(C) {}
	void apply(Tag t) {
		if (t.c) {
			c = t.c;
		}
	}
	friend std::ostream& operator<<(std::ostream &out, Tag &tag) {
		out << "tag:(" << tag.c << ")";
		return out;
	}
};

struct Info {
	std::bitset<32> color;
	Info() {}
	void apply(Tag t) {
		if (t.c) {
			color.reset();
			color.set(t.c);
		}
	}
	friend Info operator+(const Info &a, const Info &b) {
		Info ans;
		ans.color = a.color | b.color;
		return ans;
	}
	friend std::ostream& operator<<(std::ostream &out, Info &info) {
		out << "info:(" << info.color.to_string() << ")";
		return out;
	}
};

void solve() {
	int L, T, O;
	std::cin >> L >> T >> O;
	std::vector<Info> A(L);
	for (int i = 0; i < L; i++) {
		A[i].color.set(1);
	}
	LazySegmentTree<Info,Tag> tr(A);
	for (int i = 0; i < O; i++) {
		std::string op;
		int x, y, z;
		std::cin >> op >> x >> y;
		if (x > y) std::swap(x, y);
		if (op == "C") {
			std::cin >> z;
			tr.rangeApply(x-1, y, Tag(z));
		} else if (op == "P") {
			std::cout << tr.rangeQuery(x-1, y).color.count() << "\n";
		}
	}
}

int main() {
	std::cin.tie(0)->sync_with_stdio(0);
	int t = 1;
	while (t--) solve();
	return 0;
}

posted on 2024-07-14 14:11  chenfy27  阅读(18)  评论(0)    收藏  举报