POJ 2777 Count Color 线段树
2013-06-09 16:25
483 查看
/** * @file main.cpp * @brief 线段树,注意几点: * 1.输入数据中有可能有a>b的情况,需要做特殊处理 * 2.cin会超时,使用scanf * 3.线段树染色/插入的时候注意 * 如果待插入区间等于线段树区间,直接插入 * 递归处理子区间之前,需要把父亲节点的染色(如果有的话)传递给左右两个子节点,同时清除父亲节点的染色 * 4.使用位运算会使得代码更清爽 * * @author yekeren * @version 1.0.0 * @date 2013-06-09 */ #include <stdio.h> #include <string.h> #define LEFT(x) ((x) << 1) #define RIGHT(x) (((x) << 1) + 1) struct node_t { int left, right; unsigned colors; } k[410000]; /** * @brief 构建线段树 * @param root * @param left * @param right */ void build(int root, int left, int right) { k[root].left = left; k[root].right = right; if (left >= right) { return; } int mid = (left + right) >> 1; build(LEFT(root), left, mid); build(RIGHT(root), mid + 1, right); } /** * @brief 线段树染色 * @param root * @param a * @param b * @param c */ void insert(int root, int a, int b, int c) { if (a <= k[root].left && b >= k[root].right) { k[root].colors = 1 << (c - 1); return; } if (k[root].colors) { k[LEFT(root)].colors = k[root].colors; k[RIGHT(root)].colors = k[root].colors; k[root].colors = 0; } int mid = (k[root].left + k[root].right) >> 1; if (b <= mid) { insert(LEFT(root), a, b, c); } else if (a > mid) { insert(RIGHT(root), a, b, c); } else { insert(LEFT(root), a, mid, c); insert(RIGHT(root), mid + 1, b, c); } } /** * @brief 查询染色情况 * @param root * @param a * @param b * @return */ unsigned search(int root, int a, int b) { if (k[root].colors) { return k[root].colors; } int mid = (k[root].left + k[root].right) >> 1; if (b <= mid) { return search(LEFT(root), a, b); } else if (a > mid) { return search(RIGHT(root), a, b); } else { unsigned int c1 = search(LEFT(root), a, mid); unsigned int c2 = search(RIGHT(root), mid + 1, b); return c1 | c2; } } /** * @brief 交换 * @param a * @param b */ void swap(int &a, int &b) { int tmp = a; a = b; b = tmp; } int main(int argc, char *argv[]) { int l, t, o; scanf("%d%d%d", &l, &t, &o); build(1, 1, l); insert(1, 1, l, 1); while (o--) { char op[2]; scanf("%s", op); if (strcmp(op, "C") == 0) { int a, b, c; scanf("%d%d%d", &a, &b, &c); if (a > b) { swap(a, b); } insert(1, a, b, c); } else if (strcmp(op, "P") == 0) { int a, b; scanf("%d%d", &a, &b); if (a > b) { swap(a, b); } unsigned colors = search(1, a, b); int count = 0; while (colors) { if (colors & 1) { ++count; } colors = colors >> 1; } printf("%d\n", count); } } 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 (线段树、lazy思想)
- 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[线段树-求整段区间]