这道题的关键就是逆向思维(雾),把海报倒过来贴,那么对于每一张海报,只要还有空地就可以返回真
另外就是离散化的过程,不可无限制的紧缩,对于不相邻的,一定要增加一个点将它们隔开,这样在覆盖时才不会有偏差
#include <iostream>
#include <cstdio>
#include <algorithm>
using namespace std;
const int maxn = 20000 + 5;
int pl[maxn], pr[maxn], n;
int s[maxn*4], e[maxn*4];
bool covered[maxn*4];
int port[maxn], cnt;
int id[10000000+5];
void build_tree(int l, int r, int rt){
s[rt] = l;
e[rt] = r;
covered[rt] = false;
if(l != r){
build_tree(l, (l + r) / 2, rt << 1);
build_tree((l + r) / 2 + 1, r, rt << 1 | 1);
}
}
bool post(int l, int r, int rt){
if(covered[rt] == true) return false;
if(s[rt] == l && e[rt] == r){
covered[rt] = true;
return true;
}
bool res;
if(r <= (s[rt] + e[rt]) / 2) res = post(l, r, rt << 1);
else if(l > (s[rt] + e[rt]) / 2) res = post(l, r, rt << 1 | 1);
else {
bool res1 = post(l, (s[rt] + e[rt]) / 2, rt << 1);
bool res2 = post((s[rt] + e[rt]) / 2 + 1, r, rt << 1 | 1);
res = res1 || res2;
}
if(covered[rt << 1] && covered[rt << 1 | 1]) covered[rt] = true;
return res;
}
int main(){
int T;
scanf("%d", &T);
while(T--){
scanf("%d", &n);
cnt = 0;
for(int i = 0; i < n; i++){
scanf("%d%d", &pl[i], &pr[i]);
port[cnt++] = pl[i];
port[cnt++] = pr[i];
}
sort(port, port + cnt);
cnt = unique(port, port + cnt) - port;
build_tree(1, cnt, 1);
for(int i = 0; i < cnt; i++) id[port[i]] = i + 1;
int res = 0;
for(int i = n-1; i >= 0; i--){
if(post(id[pl[i]], id[pr[i]], 1)){
res ++;
}
}
printf("%d\n", res);
}
return 0;
}