Time Limit: 1000MS | Memory Limit: 65536K | |
Total Submissions: 39950 | Accepted: 12050 |
Description
Input
Output
Sample Input
2 2 4 C 1 1 2 P 1 2 C 2 2 2 P 1 2
Sample Output
21
稀里糊涂写了一发,因为没有判断a和b大小,RE两次。
改过之后提交没想到就AC了。。。我感觉有点不科学O__O "…
路过大牛,若发现代码有bug,请指出,万分感谢!
题意:有一个1——L的区间,现在有T种颜色(T <= 30)和Q次查询。
查询操作
一、C a b c 表示把区间[a, b]染成第c种颜色;
二、P a b 表示查询区间[a, b]有多少种颜色。
思路:因为T最多30,可以考虑用状态压缩记录颜色。利用好状态压缩,下面就是线段树区间更新 + 区间查询了。
AC代码:
#include <cstdio> #include <cstring> #include <algorithm> #define MAXN 100000+10 #define lson o<<1, l, mid #define rson o<<1|1, mid+1, r #define ll o<<1 #define rr o<<1|1 using namespace std; struct Tree { int l, r; int color;//记录区间颜色 用二进制表示 int lazy;//表示该区间是否被同一种颜色覆盖 }; Tree tree[MAXN<<2]; void build(int o, int l, int r) { tree[o].l = l, tree[o].r = r; tree[o].color = 1; tree[o].lazy = 1; if(l == r) return ; int mid = (l + r) >> 1; build(lson); build(rson); } void PushDown(int o) { if(tree[o].lazy) { tree[ll].lazy = tree[rr].lazy = tree[o].lazy; tree[ll].color = tree[rr].color = tree[o].color; tree[o].lazy = 0; } } void PushUp(int o) { tree[o].color = tree[ll].color | tree[rr].color; } void update(int o, int L, int R, int c) { if(L <= tree[o].l && R >= tree[o].r) { tree[o].color = (1<<(c-1)); tree[o].lazy = 1; return ; } PushDown(o); int mid = (tree[o].l + tree[o].r) >> 1; if(R <= mid) update(ll, L, R, c); else if(L > mid) update(rr, L, R, c); else { update(ll, L, mid, c); update(rr, mid+1, R, c); } PushUp(o); } int query(int o, int L, int R) { if(L <= tree[o].l && R >= tree[o].r) return tree[o].color; PushDown(o); int mid = (tree[o].l + tree[o].r) >> 1; int sum = 0; if(R <= mid) return sum | query(ll, L, R); else if(L > mid) return sum | query(rr, L, R); else return sum | query(ll, L, mid) | query(rr, mid+1, R); } int main() { int L, T, Q; while(scanf("%d%d%d", &L, &T, &Q) != EOF) { build(1, 1, L); while(Q--) { int a, b, c, t; char op[10]; scanf("%s", op); if(op[0] == 'C') { scanf("%d%d%d", &a, &b, &c); if(a > b)//注意判断a和b大小 { t = a; a = b; b = t; } update(1, a, b, c); } else { scanf("%d%d", &a, &b); if(a > b) { t = a; a = b; b = t; } int sum = query(1, a, b); int ans = 0; while(sum)//统计颜色数目 { if(sum & 1) ans++; sum >>= 1; } printf("%d\n", ans); } } } return 0; }