Files
python/TangDou/AcWing/SegmentTree/POJ2777.cpp
HuangHai 1f397eca87 'commit'
2025-08-30 18:35:01 +08:00

100 lines
2.4 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream>
using namespace std;
const int N = 100010;
#define ls u << 1
#define rs u << 1 | 1
struct Node {
int l, r;
int add, sum;
} tr[N << 2];
void pushup(int u) {
tr[u].sum = tr[ls].sum | tr[rs].sum; //因为是模拟二进制的操作,所以采用 或 运算即可完成拼接操作
}
void pushdown(int u) {
if (tr[u].add) {
tr[ls].add = tr[rs].add = tr[u].add;
tr[ls].sum = tr[rs].sum = tr[u].add;
tr[u].add = 0;
}
}
void build(int u, int l, int r) {
tr[u].l = l, tr[u].r = r;
if (l == r) {
tr[u].sum = 1; // sum记录的其实是一个30位的二进制压缩模拟数字,此时置为1表示最后一位即0位为1,是默认的颜色
return;
}
int mid = (l + r) >> 1;
build(u << 1, l, mid), build(u << 1 | 1, mid + 1, r);
pushup(u);
}
void modify(int u, int l, int r, int c) {
if (l <= tr[u].l && tr[u].r <= r) {
tr[u].add = 1 << (c - 1);
tr[u].sum = 1 << (c - 1);
return;
}
pushdown(u);
int mid = tr[u].l + tr[u].r >> 1;
if (l <= mid) modify(u << 1, l, r, c);
if (r > mid) modify(u << 1 | 1, l, r, c);
pushup(u);
}
int query(int u, int l, int r) {
if (l <= tr[u].l && tr[u].r <= r) return tr[u].sum;
int ans = 0;
pushdown(u);
int mid = tr[u].l + tr[u].r >> 1;
if (l <= mid) ans = query(u << 1, l, r);
if (r > mid) ans = ans | query(u << 1 | 1, l, r);
return ans;
}
//手工版本数字1个数
int count(int x) {
int cnt = 0;
while (x) {
cnt++;
x -= (x & -x);
}
return cnt;
}
int main() {
//加快读入
ios::sync_with_stdio(false), cin.tie(0);
int n, t, m; //区间[1,n],t种颜色,m个操作
cin >> n >> t >> m;
//构建
build(1, 1, n);
while (m--) {
char op;
int l, r;
cin >> op >> l >> r;
if (l > r) swap(l, r); //坑点题目没说哪个大哪个小,需要特判
if (op == 'C') {
int c;
cin >> c;
modify(1, l, r, c);
} else {
int ans = query(1, l, r);
int cnt = count(ans); //获取某个数二进制位1的个数
printf("%d\n", cnt);
}
}
return 0;
}