1. 搞了好久,最后发现是cnd变量没有在每次最后统计时重置。大问题一般经常出现在小地方;
2. 可以用while(c--)来给test的数量计数;
3. 学习了线段树的离散化思想
4. 再给线段树更新时,要注意条件。比如此处的做法是个可行的,检测是否全部覆盖,半覆盖还是未覆盖等。
5. 用-1, 0, 其他 来表示各种着色情况。
参考:
http://www.cppblog.com/Johnnx/archive/2009/10/13/96434.html?opt=admin
http://blog.csdn.net/lyy289065406/article/details/6799170
#include <iostream> #include <algorithm> using namespace std; struct Goda { int li; int num; // color }; struct Node { int left; int right; int color; // 1..n:fully covered }; #define MAX 20000 Node tree[MAX * 4 + 10]; int colors[10000 + 10]; int cnt = 0; int se[MAX][2]; Goda line[MAX * 2]; int cmp(const void * a, const void * b) { Goda* x = (Goda*) a; Goda* y = (Goda*) b; return x->li - y->li; } void build(int left, int right, int k) { if (left > right) return; tree[k].left = left; tree[k].right = right; tree[k].color = 0; if (left != right) { int mid = (left + right) / 2; build(left, mid, k * 2); build(mid + 1, right, k * 2 + 1); } } void update(int left, int right, int color, int k) { if (left > right) return; Node &n = tree[k]; // no common part if (left > n.right || right < n.left) return; if(n.left >= left && n.right <= right) // fully covered { n.color = color; return; } // partially covered if(n.color >= 0) { int mid = (n.left + n.right) / 2; tree[2*k].color = n.color ; tree[2*k + 1].color = n.color ; n.color = -1; } // multi-color update(left, right, color, 2*k); update(left, right, color, 2*k + 1); } void query(int k) { Node &n = tree[k]; if (n.color == 0) return; if (n.color == -1) { query(k * 2); query(k * 2 + 1); } else { if (colors[n.color] == 0) { cnt++; colors[n.color] = 1; // mark } } } int main() { int kase = 0; cin >>kase; while(kase--) { int n = 0; cin >> n; build(1, MAX, 1); memset(colors, 0, sizeof(colors)); memset(line, 0, sizeof(line)); for (int j = 0; j < n; j++) { cin >> se[j][0] >> se[j][1]; line[j * 2].li = se[j][0]; line[j * 2].num = -j - 1; // start line[j * 2 + 1].li = se[j][1]; line[j * 2 + 1].num = j + 1; // end } qsort(line, n * 2, sizeof(Goda), cmp); int tp = 0; int last = -1; for (int j = 0; j < n * 2; j++) { if (line[j].li != last) { tp++; last = line[j].li; } if (line[j].num > 0) { se[line[j].num - 1][1] = tp; } else { se[- line[j].num - 1][0] = tp; } } for (int j = 0; j < n; j++) { update(se[j][0], se[j][1], j+1, 1); } cnt = 0; query(1); cout << cnt << endl; } return 0; }