1
//
color=0表示未着色或为杂色
2
3
#include
<
cstdio
>
4
#include
<
cstring
>
5
#include
<
algorithm
>
6
using
namespace
std;
7
8
const
int
MAXN
=
40000
+
5
;
9
const
int
MAX_R
=
10000000
+
5
;
10
11
int
n, ans;
12
bool
vis[MAXN]
=
{};
13
struct
SData{
//
记录数据
14
int
b, e;
15
};
16
SData data[MAXN];
17
18
struct
node{
//
线段树节点
19
int
l, r;
20
int
color;
21
};
22
node tree[MAXN
*
3
];
23
24
struct
line{
//
s表示端点、num表示该端点是哪个poster的
25
int
s, num;
26
};
27
line L[MAXN
*
3
];
28
29
//
建树
30
void
build(
int
i,
int
ll,
int
rr){
31
tree[i].l
=
ll; tree[i].r
=
rr;
32
tree[i].color
=
0
;
//
未着色
33
if
(rr
!=
ll){
34
int
mid
=
(ll
+
rr)
/
2
;
35
build(
2
*
i, ll, mid);
36
build(
2
*
i
+
1
, mid
+
1
, rr);
37
}
38
}
39
40
//
41
void
insert(
int
i,
int
ll,
int
rr,
int
cc){
42
if
(tree[i].l
==
ll
&&
tree[i].r
==
rr){
43
tree[i].color
=
cc;
44
return
;
45
}
46
if
(tree[i].r
==
tree[i].l)
47
return
;
48
49
if
(tree[i].color
>
0
&&
tree[i].color
!=
cc){
50
tree[i
<<
1
].color
=
tree[i].color;
51
tree[(i
<<
1
)
+
1
].color
=
tree[i].color;
52
tree[i].color
=
0
;
53
}
54
int
mid
=
(tree[i].l
+
tree[i].r)
>>
1
;
55
if
(rr
<=
mid)
56
insert(i
<<
1
, ll, rr, cc);
57
else
if
(ll
>
mid)
58
insert((i
<<
1
)
+
1
, ll, rr, cc);
59
else
{
60
insert(i
<<
1
, ll, mid, cc);
61
insert((i
<<
1
)
+
1
, mid
+
1
, rr, cc);
62
}
63
}
64
65
void
sum (
int
i )
66
{
67
if
( tree[i].color )
68
{
69
if
(
!
vis[tree[i].color] )
70
{
71
vis[tree[i].color]
=
true
;
72
ans
++
;
73
}
74
return
;
75
}
76
sum( i
<<
1
);
77
sum( (i
<<
1
)
+
1
);
78
}
79
80
bool
cmp(line a, line b){
81
return
a.s
<
b.s;
82
}
83
84
int
main(){
85
int
c;
86
scanf(
"
%d
"
,
&
c);
87
while
(c
--
){
88
scanf(
"
%d
"
,
&
n);
89
90
for
(
int
i
=
0
; i
<
n; i
++
){
91
scanf(
"
%d%d
"
,
&
data[i].b,
&
data[i].e);
92
93
L[
2
*
i].s
=
data[i].b; L[
2
*
i].num
=-
(i
+
1
);
//
负数表示是poster的左端点
94
L[
2
*
i
+
1
].s
=
data[i].e; L[
2
*
i
+
1
].num
=
i
+
1
;
//
正数表示是右端点
95
}
96
97
98
//
离散化……
99
sort(L, L
+
2
*
n, cmp);
100
int
cnt
=
1
, temp
=
L[
0
].s;
101
for
(
int
i
=
0
; i
<
2
*
n; i
++
){
102
if
(L[i].s
!=
temp){
103
cnt
++
;
104
temp
=
L[i].s;
105
}
106
if
(L[i].num
<
0
)
//
如果是左端点
107
data[
-
L[i].num
-
1
].b
=
cnt;
108
else
//
如果是右端点
109
data[L[i].num
-
1
].e
=
cnt;
110
}
111
112
113
//
线段树……
114
build(
1
,
1
, cnt);
115
116
for
(
int
i
=
0
; i
<
n; i
++
){
117
insert(
1
, data[i].b, data[i].e, i
+
1
);
118
}
119
120
121
memset(vis,
0
,
sizeof
(vis));
122
ans
=
0
;
123
sum(
1
);
124
125
printf(
"
%d\n
"
, ans);
126
127
}
128
129
130
return
0
;
131
}