题目链接 http://poj.org/problem?id=2777
题意:题意是有L个单位长的画板,T种颜色,O个操作。画板初始化为颜色1。操作C讲l到r单位之间的颜色变为c,操作P查询l到r单位之间的颜色有几种。
这题区间更新很简单但是查询会发现挺麻烦的,主要是不知道怎么判断一个区间到底有几个不同的数。
由于这道题的T比较小才30,1<<30不超过int型于是可以考虑用状态来表示,1表示color1,10表示color2,100表示color3,以此类推。
然后区间更新时注意父节点的变化T[p].sum=(T[p<<1].sum | T[(p<< 1)|1].sum)两种状态相加来表示最后只要看一下着个区间有几个
1就行了。
#include <iostream> #include <cstring> #include <cstdio> using namespace std; const int inf = 1 << 30; const int M = 1e5 + 10; struct TnT { int l , r , sum , add; }T[M << 2]; void build(int l , int r , int p) { int mid = (l + r) >> 1; T[p].l = l , T[p].r = r , T[p].add = 0; if(T[p].l == T[p].r) { T[p].sum = 1; return ; } build(l , mid , p << 1); build(mid + 1 , r , (p << 1) | 1); T[p].sum = (T[p << 1].sum | T[(p << 1) | 1].sum); } int Get(int x) { int temp = 1; for(int i = 1 ; i < x ; i++) { temp <<= 1; } return temp; } void pushdown(int p) { if(T[p].add) { T[p << 1].sum = T[p].add; T[(p << 1) | 1].sum = T[p].add; T[p << 1].add = T[p].add; T[(p << 1) | 1].add = T[p].add; T[p].add = 0; } } void updata(int l , int r , int ad , int p) { int mid = (T[p].l + T[p].r) >> 1; if(T[p].l == l && T[p].r == r) { T[p].add = ad; T[p].sum = ad; return ; } pushdown(p); if(mid >= r) { updata(l , r , ad , p << 1); } else if(mid < l) { updata(l , r , ad , (p << 1) | 1); } else { updata(l , mid , ad , p << 1); updata(mid + 1 , r , ad , (p << 1) | 1); } T[p].sum = (T[p << 1].sum | T[(p << 1) | 1].sum); } int query(int l , int r , int p) { int mid = (T[p].l + T[p].r) >> 1; if(T[p].l == l && T[p].r == r) { return T[p].sum; } pushdown(p); if(mid >= r) { return query(l , r , p << 1); } else if(mid < l) { return query(l , r , (p << 1) | 1); } else { return (query(l , mid , p << 1) | query(mid + 1 , r , (p << 1) | 1)); } } int Gets(int x) { int temp = 0; while(x) { if(x & 1) { temp++; } x >>= 1; } return temp; } int main() { int l , t , o; scanf("%d%d%d" , &l , &t , &o); char cp[2]; build(1 , l , 1); for(int i = 1 ; i <= o ; i++) { int a , b , c; scanf("%s" , cp); if(cp[0] == 'C') { scanf("%d%d%d" , &a , &b , &c); if(a > b) { int gl = a; a = b; b = gl; } int gg = Get(c); updata(a , b , gg , 1); } if(cp[0] == 'P') { scanf("%d%d" , &a , &b); if(a > b) { int gl = a; a = b; b = gl; } int gg = query(a , b , 1); int counts = Gets(gg); printf("%d " , counts); } } return 0; }