标签:
单线段树单记录的套路,记录的是这个区间一致的颜色或者0
技巧是这个颜色可以用1 << (color - 1)来表示,这样结果就是所有收集的颜色取或运算,数一数有多少个1就行了。
这个一致性体现在以下合并与分割时的过程,分割只需要把一致颜色放下去(为0就不放了),合并时只有两侧区间颜色一致才记录
#define tree_merge tree_obj = tree[root<<1] == tree[root<<1|1] ? tree[root << 1] : 0
#define tree_split decl_mid; if(tree_obj){tree[root<<1]=tree[root<<1|1] = tree_obj; tree_obj = 0;}#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#define FRAME tree_frame
#define eq(x, y) (!strcmp((x), (y)))
#define times(n, i) for(int i=0; i<n; ++i)
#define range(a, b, i) for(int i=a; i<b; ++i)
/* --globals */
int a[2050000];
int M, N, T;
int tree[8050000];
#define tree_frame int l = 1, int r = N + 1, int root = 1
#define tree_obj (tree[root])
#define tree_merge tree_obj = tree[root<<1] == tree[root<<1|1] ? tree[root << 1] : 0
#define tree_split decl_mid; if(tree_obj){tree[root<<1]=tree[root<<1|1] = tree_obj; tree_obj = 0;}
#define TAG_INSIDE (l >= sl && r <= sr)
#define TAG_OUTSIDE (l >= sr || r <= sl)
#define TAG_LEAF (l == r-1)
#define decl_mid int mid = (l + r) / 2;
#define recur_left l, mid, root << 1
#define recur_right mid, r, root << 1 | 1
void build(FRAME){
if(TAG_LEAF){ tree_obj = 1; return; }
tree_split;
build(recur_left); build(recur_right);
tree_merge;
}
void update(int value, int sl, int sr, FRAME){
//printf("%d %d %d %d %d %d\n", value, sl, sr, l, r, root);
if(TAG_INSIDE) {
tree_obj = 1 << (value - 1);
return ;
}
if(TAG_OUTSIDE){ return; }
tree_split;
update(value, sl, sr, recur_left );
update(value, sl, sr, recur_right);
tree_merge;
}
int result;
void query_impl(int sl, int sr, FRAME){
if(TAG_INSIDE){
if(tree_obj != 0){
result |= tree_obj;
return;
}
}
if(TAG_OUTSIDE){ return; }
tree_split;
query_impl(sl, sr, recur_left);
query_impl(sl, sr, recur_right);
tree_merge;
}
int query(int sl, int sr){
result = 0;
query_impl(sl, sr);
int ans = 0;
// printf("%x\n", result);
while(result > 0) ans += result & 1, result >>= 1;
return ans;
}
int main(){
scanf("%d%d%d", &N, &T, &M);
build();
while(M--){
int a, b, c;
char tmp[1024];
scanf("%s%d%d", tmp, &a, &b);
if(a > b) std::swap(a, b);
if(eq(tmp, "C")) {
scanf("%d", &c);
update(c, a, b+1);
}
if(eq(tmp, "P")){
printf("%d\n", query(a, b+1));
}
}
return 0;
}
标签:
原文地址:http://blog.csdn.net/pochioly/article/details/42073059