题目链接:http://poj.org/problem?id=2777
题意:给你一段长L的板子, 刚开始染了1号颜色,给你q个操作,
1、C A B val 从A到B染成val 色
2、P A B 查询从A 到B 一共有多少种不同的颜色
思路:由于一共30种颜色,所以用一个30位的二进制串就可以表示了;
如果染val色 那么让ans = (1 << val);
正好学习了一下bitset,
// bitset的使用,定义:bitset<32> s; 清空 s.reset(), 计算1的个数,s.count();
#include <iostream>
#include <cstdio>
#include <bitset>
using namespace std;
const int maxn = 1e5 + 10;
struct node {
int l, r, lazy;
bitset<32> s;
}e[maxn << 2];
void pushup(int cur){
e[cur].s = (e[cur << 1].s | e[cur << 1 | 1].s);
}
void pushdown(int cur){
if(e[cur].lazy) {
e[cur << 1].lazy = e[cur].lazy;
e[cur << 1].s = (1 << e[cur].lazy);
e[cur << 1 | 1].lazy = e[cur].lazy;
e[cur << 1 | 1].s = (1 << e[cur].lazy);
e[cur].lazy = 0;
}
}
void build(int l, int r, int cur){
e[cur].l = l;
e[cur].r = r;
e[cur].lazy = 0;
e[cur].s.reset();
if(l == r){
e[cur].s = (1 << 1);
return ;
}
int mid = l + r >> 1;
build(l, mid, cur << 1);
build(mid + 1, r, cur << 1 | 1);
pushup(cur);
}
void update(int l, int r, int cur, int cl, int cr, int val){
if(cl <= l && r <= cr) {
e[cur].lazy = val;
e[cur].s = (1 << val);
return ;
}
pushdown(cur);
int mid = l + r >> 1;
if(cl <= mid) {
update(l, mid, cur << 1, cl, cr, val);
}
if(cr > mid)
update(mid + 1, r, cur << 1 | 1, cl, cr, val);
pushup(cur);
}
bitset<32> query(int l, int r, int cur, int cl, int cr){
if(cl <= l && r <= cr){
return e[cur].s;
}
pushdown(cur);
bitset<32> ans;
ans.reset();
int mid = l + r >> 1;
if(cl <= mid)
ans = (ans | query(l, mid, cur << 1, cl, cr));
if(cr > mid)
ans = (ans | query(mid + 1, r, cur << 1 | 1, cl, cr));
return ans;
}
int main(){
int n, m, q;
scanf("%d%d%d", &n, &m, &q);
build(1, n, 1);
while(q--){
char op[2];
int l, r, val;
scanf("%s%d%d", op, &l, &r);
if(l > r) swap(l, r);
if(op[0] == 'C') {
scanf("%d", &val);
update(1, n, 1, l, r, val);
}
else
cout << query(1, n, 1, l, r).count() <<endl;
}
return 0;
}