POJ 2777 Count Color 线段树 + lazy标记
2013-10-12 22:43
417 查看
/** * 线段树 + lazy标记 * 维护区间所含颜色种数,依题种数小于30,很容易想到用位压缩记录状态, * 在更新的时候用 按位与(a | b) 就能合并两个区间所有的颜色,询问的时候返回 * 区间所记录的颜色种数(一个int型的数),返回后,再计算各位上含1的个数即为种数。 * 规定第i种颜色为(1<<i) * 其次是更新,用个lazy标记表示是否整个区间都染成同一种颜色即可。 */ #include <cstdio> #include <iostream> #include <cstring> #include <cmath> #include <string> #include <queue> #include <map> #include <vector> #include <algorithm> #define DEBUG 0 #define INF 0x1fffffff #define MAXN 100005 #define OUTSTARS printf("*****************************\n"); typedef long long LL; using namespace std; struct Seg { int l, r, c; int set; } tree[MAXN << 4]; int l, t, o; void build(int l, int r, int id) { tree[id].l = l; tree[id].r = r; tree[id].set = 1; tree[id].c = 1<<1; if(l == r) return ; int mid = (l + r) / 2; build(l, mid, id << 1); build(mid + 1, r, id << 1 | 1); } void push_down(int id) { if(tree[id].set) { tree[id<<1].set = tree[id].set; tree[id<<1].c = tree[id].c; tree[id<<1|1].set = tree[id].set; tree[id<<1|1].c = tree[id].c; tree[id].set = 0; } } int query(int L, int R, int id) { int ll = 0, rr = 0; push_down(id); if(L <= tree[id].l && R >= tree[id].r) { return tree[id].c; } int mid = (tree[id].l + tree[id].r) / 2; if(L <= mid) ll = query(L, R, id << 1); if(R > mid) rr = query(L, R, id << 1 | 1); return ll | rr; } void update(int L, int R, int c, int id) { int mid = (tree[id].l + tree[id].r) / 2; push_down(id); if(L <= tree[id].l && R >= tree[id].r) { tree[id].set = 1; tree[id].c = 1 << c; } else { if(L <= mid) update(L, R, c, id << 1); if(R > mid) update(L, R, c, id << 1 | 1); tree[id].c = tree[id<<1].c | tree[id<<1|1].c; } } /** 计算颜色种数,即计算一个数中的各位上1的总数 */ int cal_bit(int x) { int ret = 0; for(; x; x >>= 1) if(x & 1) ret ++; return ret; } int main() { while(scanf("%d%d%d", &l, &t, &o) != EOF) { build(1, l, 1); for(int i = 1; i <= o; i ++) { getchar(); char ch = getchar(); if(ch == 'C') { int L, R, c; scanf("%d%d%d", &L, &R, &c); if(L > R) swap(L, R); update(L, R, c, 1); } else if(ch == 'P') { int L, R; scanf("%d%d", &L, &R); if(L > R) swap(L, R); printf("%d\n", cal_bit(query(L, R, 1))); } } } return 0; }
相关文章推荐
- POJ-2777 Count Color(线段树)
- POJ 2777 Count Color (线段树)
- poj 2777 Count Color(线段树区间更新+位运算)
- [POJ 2777]Count Color(线段树)
- POJ 题目2777 Count Color(线段树,区间查询染色数)
- POJ 2777 Count Color【线段树】
- POJ:2777-Count Color(线段树+状压)
- POJ 2777 Count Color 线段树
- POJ 2777 Count Color(线段树+位运算)
- poj 2777 Count Color (线段树 + 覆盖标记)
- POJ 2777 Count Color 线段树
- poj 2777 Count Color(线段树区间修改)
- Poj 2777 Count Color(线段树基础)
- poj 2777 Count Color - 线段树 - 位运算优化
- POJ 2777 Count Color(线段树)
- POJ 2777 Count Color (二进制或 线段树)
- poj 2777 Count Color (线段树区间更新)
- POJ训练计划2777_Count Color(线段树/成段更新/区间染色)
- POJ2777——Count Color(线段树)
- POJ 2777 Count Color(线段树+位运算)