线段树+离散化。离散化的时候要记得将端点的左边一个点和右边一个点也加进去,不然是错的。
也有不用线段树的做法,例如用个堆,参考这篇点这里。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
#define N 60100
#define ls (p<<1)
#define rs (p<<1|1)
#define mid(p) (t[p].l+t[p].r>>1)
struct segmentTree{
int l,r,v;
int tag;
}t[N*4];
void lazy(int p){
if (t[p].tag){
t[ls].v=t[rs].v=t[ls].tag=t[rs].tag=t[p].tag;
t[p].tag=0;
}
}
void build(int l,int r,int p){
t[p].l=l;t[p].r=r;t[p].tag=t[p].v=0;
if (t[p].l==t[p].r) return;
int m=mid(p);
build(l,m,ls);
build(m+1,r,rs);
}
void update(int l,int r,int p,int v){
if (l==t[p].l&&r==t[p].r){
t[p].tag=t[p].v=v;
return;
}
lazy(p);
int m=mid(p);
if (r<=m) {
update(l,r,ls,v);
}
else if (l>m){
update(l,r,rs,v);
}
else {
update(l,m,ls,v);
update(m+1,r,rs,v);
}
}
int query(int pos,int p){
if (t[p].l==t[p].r) return t[p].v;
lazy(p);
int m=mid(p);
if (pos<=m){
return query(pos,ls);
}
else {
return query(pos,rs);
}
}
int vis[N],b[N];
int n;
struct poster{
int be,ed;
}s[N];
int discret(){
int tn=0;
int i;
for(i=1;i<=n;++i){
b[++tn]=s[i].be;
b[++tn]=s[i].be+1;
b[++tn]=s[i].be-1;
b[++tn]=s[i].ed;
b[++tn]=s[i].ed+1;
b[++tn]=s[i].ed-1;
}
sort(b+1,b+tn+1);
int ret=unique(b+1,b+tn+1)-b;
return ret;
}
int bsch(int l,int r,int v){
int m;
while(l<=r){
m=l+r>>1;
if (b[m]==v) return m;
else if (b[m]<v) l=m+1;
else r=m-1;
}
}
int main(){
int cas,i,tn,ans,tmp;
scanf("%d",&cas);
while(cas--){
scanf("%d",&n);
for(i=1;i<=n;++i){
scanf("%d%d",&s[i].be,&s[i].ed);
}
tn=discret();
build(1,tn,1);
for(i=1;i<=n;++i){
update(bsch(1,tn,s[i].be),bsch(1,tn,s[i].ed),1,i);
}
ans=0;
memset(vis,0,sizeof(vis));
vis[0]=1;
for(i=1;i<=tn;++i){
tmp=query(i,1);
if (vis[tmp]==0){
ans++;
vis[tmp]=1;
}
}
printf("%d\n",ans);
}
return 0;
}