在一面墙上贴海报,求最终能看到的海报数量。
先把所有数离散化,映射为新的数,在用线段树模板就行了。
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
int col[1 << 17];
int ans;
typedef struct S {
int pos, id;
} NODE;
NODE node[20010];
bool cmp(NODE a, NODE b) {
return a.pos < b.pos;
}
int ls[20010];
int vis[40010];
void pushdown(int rt, int len) {
if (col[rt] != -1) {
col[rt << 1] = col[rt << 1 | 1] = col[rt];
col[rt] = -1;
}
}
void update(int L, int R, int c, int l, int r, int rt) {
if (L <= l && R >= r) {
col[rt] = c;
return;
}
pushdown(rt, r - l + 1);
int m = (l + r) >> 1;
if (L <= m)
update(L, R, c, lson);
if (R > m)
update(L, R, c, rson);
}
void query(int l, int r, int rt) {
if (col[rt] != -1) {
if (!vis[col[rt]]) {
vis[col[rt]] = 1;
++ans;
}
return;
}
if (l == r)
return;
int m = (l + r) >> 1;
query(lson);
query(rson);
}
int main() {
int T, i, j, n, max;
scanf("%d", &T);
while (T--) {
scanf("%d", &n);
memset(col, -1, sizeof (col));
memset(vis,0,sizeof(vis));
for (i = 0; i < n; ++i) {
node[i << 1].id = i << 1;
scanf("%d", &node[i << 1].pos);
node[i << 1 | 1].id = i << 1 | 1;
scanf("%d", &node[i << 1 | 1].pos);
}
sort(node, node + n + n, cmp);
ls[node[0].id] = 0;
for (i = 1; i < n + n; ++i) {
if (node[i].pos == node[i - 1].pos) {
ls[node[i].id] = ls[node[i - 1].id];
} else if (node[i].pos == node[i - 1].pos + 1) {
ls[node[i].id] = ls[node[i - 1].id] + 1;
} else {
ls[node[i].id] = ls[node[i - 1].id] + 2;
}
}
max = ls[node[n + n - 1].id];
for (i = 0; i < n; ++i) {
update(ls[i << 1], ls[i << 1 | 1], i, 0, max, 1);
}
ans = 0;
query(0, max, 1);
printf("%d\n", ans);
}
return 0;
}