这道题主要是把所有坐标记录在数组里,排序,去重,把每个数和1-N进行一 一对应也就是离散化。不过有个问题是,这样做后1-10 1-4 6-10这组数据会出现错误。解决办法是在离散化后的数组中,若相邻两个数相差大于1,就在其中插入一个介于他们俩之间的数。
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <vector>
#include <queue>
#include <cstring>
#define maxn 10005
#define INF 10000000
using namespace std;
struct Node{
int l, r;
}node[maxn];
int add[maxn<<4], vis[maxn], p1[maxn<<1], p2[maxn<<2];
void Pushdown(int n){
if(add[n] != -1){
add[n<<1] = add[n];
add[n<<1|1] = add[n];
add[n] = -1;
}
}
void Update(int n, int L, int R, int l, int r, int s){
if(l == L && R == r){
add[n] = s;
return ;
}
Pushdown(n);
int mid = (L + R) >> 1;
if(r <= mid)
Update(n<<1, L, mid, l, r, s);
else if(l > mid)
Update(n<<1|1, mid+1, R, l, r, s);
else{
Update(n<<1, L, mid, l, mid, s);
Update(n<<1|1, mid+1, R, mid+1, r, s);
}
}
void Query(int n, int L, int R, int &s){
if(add[n] != -1){
if(vis[add[n]] == 0){
s++;
vis[add[n]] = 1;
}
return ;
}
if(L == R)
return ;
int mid = (L + R) >> 1;
Query(n<<1, L, mid, s);
Query(n<<1|1, mid+1, R, s);
}
int main(){
//freopen("in.txt", "r", stdin);
int t;
cin >> t;
while(t--){
memset(vis, 0, sizeof(vis));
memset(add, -1, sizeof(add));
int n, cnt = 0;
scanf("%d", &n);
for(int i = 1; i <= n; i++){
scanf("%d%d", &node[i].l, &node[i].r);
p1[cnt++] = node[i].l;
p1[cnt++] = node[i].r;
}
sort(p1, p1+cnt);
cnt = unique(p1, p1+cnt) - p1;
int c = 0;
p2[c++] = p1[0];
for(int i = 1; i < cnt; i++){
if(p1[i] > p1[i-1]+2)
p2[c++] = p1[i-1] + 1;
p2[c++] = p1[i];
}
cnt = c;
for(int i = 1; i <= n; i++){
int t1= lower_bound(p2, p2+cnt, node[i].l) - p2;
int t2 = lower_bound(p2, p2+cnt, node[i].r) - p2;
Update(1, 1, cnt, t1+1, t2+1, i);
}
int s = 0;
Query(1, 1, cnt, s);
cout << s << endl;
}
return 0;
}