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;
}