Contents
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290



#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <algorithm>
#include <set>
using namespace std;
#define Lson(x) (x<<1)
#define Rson(x) (x<<1|1)
#define Mid(x,y) ((x+y)>>1)
#define MAXN 10010

int pos;
set <int> s;
//n的上限是1万,num存区间,所以上限是2n,temp存离散化后的数组,上限是4n(因为可能都相差大于1,就是num的两倍了),
//又因为要把temp复制回num数组,所以num也开4n,线段树就要开4*4n,但杭电给的数据好像没有这么恶心,似乎没有到达这个极限,
//所以我用线段树开8n也水过了
//300MS左右,我师傅的版本是79MS
//set可以改为用数组,二分查找用c++库里自带的 速度就应该会提上来的
int num[4 * MAXN];
int temp[MAXN * 4];
//vis[MAXN], ans[MAXN * 4];

struct Node{
int left;
int right;
int mark;
}node[MAXN * 16], tmp[16 * MAXN];

void hash_s()
{

int index = 1;
for(int i = 0; i < pos; i++){
temp[index++] = num[i];
if(num[i+1] - num[i] > 1)
temp[index++] = num[i] + 1;
}
pos = index - 1; //pos从 1 开始
memcpy(num, temp, sizeof(num));
//for(int i = 1; i <= pos; i++)
//printf(":: %d\n", num[i]);
}

int Search(int x){
int left , right , mid;
left = 1 , right = pos;
while(left <= right){
mid = (left+right)>>1;
if(num[mid] == x)
return mid; //在这里通过mid离散化为num里的值离散化为num的序列
else if(num[mid] < x)
left = mid+1;
else
right = mid-1;
}
}

void push_down(int pos)
{

if(node[pos].mark){
node[Lson(pos)].mark = node[pos].mark;
node[Rson(pos)].mark = node[pos].mark;
node[pos].mark = 0;
}
}

void build_tree(int left, int right, int pos)
{

node[pos].left = left;
node[pos].right = right;
node[pos].mark = 0;
if(left == right)
return ;
int mid = Mid(left, right);
build_tree(left, mid, Lson(pos));
build_tree(mid + 1, right, Rson(pos));
}

void update(int left, int right, int value, int pos)
{

if(left <= node[pos].left && node[pos].right <= right){
node[pos].mark = value;
return ;
}
push_down(pos);
int mid = Mid(node[pos].left, node[pos].right);
if(right <= mid)
update(left, right, value, Lson(pos));
else if(left > mid)
update(left, right, value, Rson(pos));
else{
update(left, mid, value, Lson(pos));
update(mid + 1, right, value, Rson(pos));
}
}

int query(int left, int right, int pos)
{

if(node[pos].left == node[pos].right){
return node[pos].mark;
}

push_down(pos);

int mid = Mid(node[pos].left, node[pos].right);
if(right <= mid)
return query(left, right, Lson(pos));
else
return query(left, right, Rson(pos));
}

int main()
{

freopen("input.txt", "r", stdin);
int T, n;
scanf("%d", &T);
while(T--){
scanf("%d", &n);
pos = 0;
for(int i = 1; i <= n; i++){
scanf("%d%d", &tmp[i].left, &tmp[i].right);//先保存最初的区间
num[pos++] = tmp[i].left, num[pos++] = tmp[i].right;
}
sort(num, num + pos);
pos = unique(num, num + pos) - num;//忽略重复的,pos是从0开始的
hash_s();
for(int i = 1; i <= n; i++){
tmp[i].left = Search(tmp[i].left);//把区间改为离散化后的区间
tmp[i].right = Search(tmp[i].right);
//printf("%d %d\n", tmp[i].left, tmp[i].right);
}
build_tree(1, pos, 1);
//printf("pos: %d\n\n",pos);
for(int i = 1; i <= n; i++)
update(tmp[i].left, tmp[i].right, i, 1);

s.clear();
for(int i = 1; i <= pos; i++)
{
int x = query(i, i, 1);
if(x != 0)// 注意,这里空的区间则mark为最初的0,说明没有贴海报,这一段就不应该算入
s.insert(query(i, i, 1));
}
/*set<int>::iterator it;
for(it = s.begin(); it != s.end(); it++)
printf("wo :: %d ", *it);// 中间空着的是0*/


printf("%d\n" , s.size());

/*int index = 1, x;
memset(vis, 0, sizeof(vis));
for(int i = 1; i <= pos; i++){
x = query(i, i, 1);
printf("xx %d\n ", x);
if(!vis[x] && x != 0){
vis[x] = 1;
ans[index++] = x;
}
}
for(int i = 1; i <= index - 1; i++)
printf("ans:: %d ", ans[i]);
printf("x :: %d", x - 1);*/


}
return 0;
}


/*
*输入:
2
5
1 4000000
2000000 6000000
8000000 10000000
3000000 4000000
7000000 10000000
5
1 4
2 6
8 10
3 4
7 10

输出:
4
4
*/


//////////////////////////////////////////////////////////////////////////////


#include <cstdio>
#include <cstring>
#include <algorithm>
#define N 10005

using namespace std;

int tree[N << 4], n, maxs, tmp[N << 2], tmpsz;
bool mark[N];

struct qu
{
int l, r;
} arr[N];

inline void init()
{

memset(tree, tmpsz = 0, sizeof(tree));
memset(mark, false, sizeof(mark));
mark[0] = true;
}

void update(int ll, int rr, int val, int l = 1, int r = maxs, int i = 1)
{

if (ll <= l && rr >= r)
{
tree[i] = val;
return;
}
if (tree[i])
{
tree[i << 1] = tree[i << 1 | 1] = tree[i];
tree[i] = 0;
}
int m = (l + r) >> 1;
if (m >= ll)
update(ll, rr, val, l, m, i << 1);
if (m < rr)
update(ll, rr, val, m + 1, r, i << 1 | 1);
}

int query(int l = 1, int r = maxs, int i = 1)
{

if (l == r)
{
if (!mark[tree[i]])
{
mark[tree[i]] = true;
return 1;
}
return 0;
}
if (tree[i])
{
tree[i << 1] = tree[i << 1 | 1] = tree[i];
tree[i] = 0;
}
int m = (l + r) >> 1;
return query(l, m, i << 1) + query(m + 1, r, i << 1 | 1);
}

int main(int argc, char* argv[])
{

int t;
scanf("%d", &t);
while (t--)
{
scanf("%d", &n);
init();
for (int i = 1; i <= n; ++i)
{
scanf("%d%d", &arr[i].l, &arr[i].r);
tmp[++tmpsz] = arr[i].l;
tmp[++tmpsz] = arr[i].r;
}
sort(tmp + 1, tmp + tmpsz + 1);
tmpsz = unique(tmp + 1, tmp + tmpsz + 1) - tmp - 1;
for (int i = tmpsz; i > 1; --i) if (tmp[i] - tmp[i - 1] > 1)
tmp[++tmpsz] = tmp[i] - 1;
sort(tmp + 1, tmp + tmpsz + 1);
for (int i = 1; i <= n; ++i)
{
arr[i].l = lower_bound(tmp + 1, tmp + tmpsz + 1, arr[i].l) - tmp;
arr[i].r = lower_bound(tmp + 1, tmp + tmpsz + 1, arr[i].r) - tmp;
maxs = max(maxs, arr[i].l);
maxs = max(maxs, arr[i].r);
}
for (int i = 1; i <= n; ++i)
update(arr[i].l, arr[i].r, i);
printf("%d\n", query());
}
return 0;
}

//转: lioasdfghjkl.github.io
Contents