首页 > 代码库 > poj 2777 Counting Colors
poj 2777 Counting Colors
单线段树单记录的套路,记录的是这个区间一致的颜色或者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; }
poj 2777 Counting Colors
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。