题目
题目在这里
思路
一共不超过30种颜色,可以bitset
数组替换线段树中的int
数组。套线段树模版就行了。
代码
#include <cstdio>
#include <algorithm>
#include <bitset>
using namespace std;
const int maxn = 1e5+5;
int L, T, O;
bitset<32>tree[4*maxn], lz[4*maxn];
void buildtree(int k, int l, int r) {
if(l == r) {
tree[k] = 2;
return ;
}
int m = (l+r) / 2;
int left = k*2, right = k*2+1;
buildtree(left, l, m);
buildtree(right, m+1, r);
tree[k] = tree[left]|tree[right];
}
void pushdown(int k) {
if(lz[k] != 0) {
lz[k*2] = lz[k];
lz[k*2+1] = lz[k];
tree[k*2] = lz[k];
tree[k*2+1] = lz[k];
lz[k].reset();
}
}
void update(int k, int l, int r, int L, int R, int c) {
if(r <= R && l >= L) {
tree[k].reset();
tree[k].set(c);
lz[k].reset();
lz[k].set(c);
return ;
}
pushdown(k);
int m = (l+r) >> 1;
if(m >= L)
update(k*2, l, m, L, R, c);
if(m < R)
update(k*2+1, m+1, r, L, R, c);
tree[k] = tree[k*2] | tree[k*2+1];
return ;
}
bitset<32> query(int k, int l, int r, int L, int R) {
if(l >= L && r <= R)
return tree[k];
if(r < L || l > R)
return 0;
pushdown(k);
bitset<32> s(0);
int m = (l+r) >> 1;
if(m >= L) s |= query(k*2, l, m, L, R);
if(m < R) s |= query(k*2+1, m+1, r, L, R);
return s;
}
int main(void)
{
/* freopen("in.txt", "r", stdin); */
char ch;
int a, b, c;
scanf("%d%d%d", &L, &T, &O);
buildtree(1, 1, L);
for(int i = 0; i < O; ++i) {
scanf(" %c", &ch);
if(ch == 'C') {
scanf("%d%d%d", &a, &b, &c);
update(1, 1, L, a, b, c);
} else {
scanf("%d%d", &a, &b);
if(a > b)
swap(a, b);
printf("%d\n", query(1, 1, L, a, b).count());
}
}
return 0;
}