poj 2777 Count Color
2015-01-03 20:20
218 查看
问题描述:http://poj.org/problem?id=2777
理解:
一道线段树的题。
统计一块木板上出现颜色的种类。相对纯粹和的累加还是不一样。涂上新的颜色会被覆盖掉,找不到合适的容器。
还有lazy算法,避免每一次搜索得把所有叶子节点遍历一遍
细节:
1."P A B" (here A, B, C are integers, and A may be larger than B) 意味着出现此种情况要交换
2.节点里还是不要Mid(),占空间。
解决办法:
1.用一个32位的整数,记录每一种颜色出现。解决覆盖可以用左右叶子节点 | 。计算颜色种数用移位>>。
2.两个操作
Color()这个函数的递归让我挺晕的。据我目前看来的递归函数,在调用自身之前常往下一步走,也就是“push up”, 调用自身之后,会反馈回来,
也就是“push down”。查询这个操作里,因为要用lazy算法,终止条件几乎都是,当前节点范围被s、e覆盖。
Output()这个函数里要返回颜色这个32位整数。在最后一个判断条件里是用符号 | 进行种数的累加,而不是单纯的加和,我就wa在这里了。
3.标记flag为1的时候表示只有当前区间只有一种颜色(可以选择push down);为0的时候就已经有多种颜色了。
代码:
理解:
一道线段树的题。
统计一块木板上出现颜色的种类。相对纯粹和的累加还是不一样。涂上新的颜色会被覆盖掉,找不到合适的容器。
还有lazy算法,避免每一次搜索得把所有叶子节点遍历一遍
细节:
1."P A B" (here A, B, C are integers, and A may be larger than B) 意味着出现此种情况要交换
2.节点里还是不要Mid(),占空间。
解决办法:
1.用一个32位的整数,记录每一种颜色出现。解决覆盖可以用左右叶子节点 | 。计算颜色种数用移位>>。
2.两个操作
Color()这个函数的递归让我挺晕的。据我目前看来的递归函数,在调用自身之前常往下一步走,也就是“push up”, 调用自身之后,会反馈回来,
也就是“push down”。查询这个操作里,因为要用lazy算法,终止条件几乎都是,当前节点范围被s、e覆盖。
Output()这个函数里要返回颜色这个32位整数。在最后一个判断条件里是用符号 | 进行种数的累加,而不是单纯的加和,我就wa在这里了。
3.标记flag为1的时候表示只有当前区间只有一种颜色(可以选择push down);为0的时候就已经有多种颜色了。
代码:
#include <iostream> #include <cstdio> #define N 100050 using namespace std; struct Node { int L, R, flag; int C; //32位整数 int Mid() { return (L + R)/2; } } tree[N * 4]; int amount(int c) { int a = 0; while(c != 0) { if((c & 1) == 1) { a++; } c >>= 1; } return a; } /* void print(int root) { cout << tree[root].L << " " << tree[root].R << endl; cout << tree[root].flag << endl; cout << amount(tree[root].C) << endl << endl; } */ void BuildTree(int root, int L, int R) { tree[root].L = L; tree[root].R = R; tree[root].C = 1; tree[root].flag = 1;// if(L != R) { BuildTree(root * 2 + 1, L, (L + R)/2); BuildTree(root * 2 + 2, (L + R)/2 + 1, R); } } void color(int root, int s, int e, int t) { if(s <= tree[root].L && tree[root].R <= e) { tree[root].C = (1 << (t - 1)); tree[root].flag = 1; //print(root); return; } if(tree[root].flag) { tree[root * 2 + 1].C = tree[root * 2 + 2].C = tree[root].C; tree[root * 2 + 1].flag = tree[root * 2 + 2].flag = 1; tree[root].flag = 0; } if(e <= tree[root].Mid()) { color(root * 2 + 1, s, e, t); } else if(s > tree[root].Mid()) { color(root * 2 + 2, s, e, t); } else { color(root * 2 + 1, s, tree[root].Mid(), t); color(root * 2 + 2, tree[root].Mid() + 1, e, t); } tree[root].C = tree[root * 2 + 1].C | tree[root * 2 + 2].C; tree[root].flag = 0; } int output(int root, int s, int e) { if((s <= tree[root].L && tree[root].R <= e) || tree[root].flag) { return tree[root].C; } if(e <= tree[root].Mid()) { return output(root * 2 + 1, s, e); } else if(s > tree[root].Mid()) { return output(root * 2 + 2, s, e); } else { return output(root * 2 + 1, s, tree[root].Mid()) | output(root * 2 + 2, tree[root].Mid() + 1, e); } } int main() { int L, T, O; scanf("%d%d%d", &L, &T, &O); //cin >> L >> T >> O; BuildTree(0, 1, L); for(int i = 0; i < O; i++) { char c; int s, e, t; getchar(); scanf("%c", &c); //cin >> c; if(c == 'C') { scanf("%d%d%d", &s, &e, &t); //cin >> s >> e >> t; color(0, s, e, t); /* for(int i = 0; i < L + 1; i++) { print(i); } */ } else if(c == 'P') { scanf("%d%d", &s, &e); //cin >> s >> e; if(s > e) swap(s, e); printf("%d\n", amount(output(0, s, e))); //cout << A << endl; } } 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(位运算+线段树区间更新 可用bitset记录)
- 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