POJ 2777 解题报告
2014-12-13 10:09
295 查看
这道题看着就是segment tree的题,但是trick的地方很多。
首先是颜色的表示。用int数组的话粗略计算了下感觉会超内存,于是用的是set<int>,可以想到,这使得速度降低了很多。看到discuss上面一个同学说的才恍然大悟,因为color的数目不大于30,所以一个32位int就绰绰有余,而且int的位运算天然地就比set简单快捷。
其次是lazy update。我其实不是很清楚这个有多大影响,不过应该很重要。
再次是POJ的一些特性,g++的时候过不了,改成c++就以900+ms过了。然后将cin, cout改成scanf,printf就有了现在360ms的程序。
首先是颜色的表示。用int数组的话粗略计算了下感觉会超内存,于是用的是set<int>,可以想到,这使得速度降低了很多。看到discuss上面一个同学说的才恍然大悟,因为color的数目不大于30,所以一个32位int就绰绰有余,而且int的位运算天然地就比set简单快捷。
其次是lazy update。我其实不是很清楚这个有多大影响,不过应该很重要。
再次是POJ的一些特性,g++的时候过不了,改成c++就以900+ms过了。然后将cin, cout改成scanf,printf就有了现在360ms的程序。
2777 | Accepted | 3268K | 360MS | C++ | 3762B |
/* ID: thestor1 LANG: C++ TASK: poj2777 */ #include <iostream> #include <fstream> #include <cmath> #include <cstdio> #include <cstring> #include <limits> #include <string> #include <vector> #include <list> #include <set> #include <map> #include <queue> #include <stack> #include <algorithm> #include <cassert> using namespace std; class Node { public: // as the number of different colors is less than 30, a single int should be sufficient int colors; bool delay; Node() : colors(0), delay(false) {} }; void update(vector<Node> &segmentTree, int left, int right, int index, const int lindex, const int rindex, const int color) { if (lindex <= left && right <= rindex) { segmentTree[index].colors = (1 << color); segmentTree[index].delay = true; return; } if (left != right) { int mid = left + ((right - left) >> 1); if (segmentTree[index].delay) { segmentTree[2 * index + 1].colors = segmentTree[index].colors; segmentTree[2 * index + 1].delay = true; segmentTree[2 * index + 2].colors = segmentTree[index].colors; segmentTree[2 * index + 2].delay = true; segmentTree[index].delay = false; } if (rindex <= mid) { update(segmentTree, left, mid, 2 * index + 1, lindex, rindex, color); } else if (lindex >= mid + 1) { update(segmentTree, mid + 1, right, 2 * index + 2, lindex, rindex, color); } else { update(segmentTree, left, mid, 2 * index + 1, lindex, rindex, color); update(segmentTree, mid + 1, right, 2 * index + 2, lindex, rindex, color); } segmentTree[index].colors = segmentTree[2 * index + 1].colors | segmentTree[2 * index + 2].colors; } } void query(vector<Node> &segmentTree, int left, int right, int index, const int lindex, const int rindex, int &colors) { if (lindex <= left && right <= rindex) { colors |= segmentTree[index].colors; return; } if (left != right) { int mid = left + ((right - left) >> 1); if (segmentTree[index].delay) { segmentTree[2 * index + 1].colors = segmentTree[index].colors; segmentTree[2 * index + 1].delay = true; segmentTree[2 * index + 2].colors = segmentTree[index].colors; segmentTree[2 * index + 2].delay = true; segmentTree[index].delay = false; } if (rindex <= mid) { query(segmentTree, left, mid, 2 * index + 1, lindex, rindex, colors); } else if (lindex >= mid + 1) { query(segmentTree, mid + 1, right, 2 * index + 2, lindex, rindex, colors); } else { query(segmentTree, left, mid, 2 * index + 1, lindex, rindex, colors); query(segmentTree, mid + 1, right, 2 * index + 2, lindex, rindex, colors); } } } int cntcolors(int colors) { int cnt = 0; while (colors) { colors &= colors - 1; cnt++; } return cnt; } int main() { int L, T, O; // cin >> L >> T >> O; scanf("%d%d%d", &L, &T, &O); // cout << "L:" << L << ", T: " << T << ", O: " << O << endl; vector<Node> segmentTree(4 * L); update(segmentTree, 0, L - 1, 0, 0, L - 1, 0); char type; int a, b, c; for (int t = 0; t < O; ++t) { // cin >> type >> a >> b; type = 'A'; while (type != 'C' && type != 'P') { scanf("%c", &type); } scanf("%d%d", &a, &b); a--, b--; if (a > b) { int tmp = a; a = b; b = tmp; } if (type == 'C') { // color // cin >> c; scanf("%d", &c); c--; update(segmentTree, 0, L - 1, 0, a, b, c); } else { // print int colors = 0; query(segmentTree, 0, L - 1, 0, a, b, colors); // cout << "[debug]colors: " << colors << endl; // cout << cntcolors(colors) << endl; printf("%d\n", cntcolors(colors)); } } return 0; }
相关文章推荐
- poj 2777-Count Color解题报告
- poj 2777 count color解题报告【线段树】
- POJ 1045 解题报告
- POJ 1835 宇航员 解题报告
- POJ 2246 Matrix Chain Multiplication 解题报告(栈)
- POJ - 1442 Black Box解题报告(求第k小的数 堆)
- POJ 1637 网络流判混合欧拉回路 解题报告
- POJ 2719 Faulty Odometer 解题报告
- 单调队列 - 兼 ACM PKU POJ 3250 及 2823 解题报告 [转]
- poj1328解题报告.
- POJ - 1195 Mobile phones解题报告(二维树状数组)
- POJ 1144 Tarjan 割点 解题报告
- POJ_1007:DNA Sorting解题报告
- POJ 3160 Father Christmas flymouse 解题报告
- poj 1003 Hangover 解题报告
- POJ 2159 解题报告
- 【POJ 1025 Department 解题报告】
- POJ1326解题报告
- poj2472解题报告——化用Dijkstra算法
- 【原】 POJ 1088 滑雪 递归+memoization 解题报告