//线段树区间覆盖 #include<cstdio> #include<cstring> #include<iostream> #include<algorithm> using namespace std; const int N=100010; int flag; struct node{ int l,r; //vis 是这块区域是否完全被覆盖 bool vis; }tr[N<<2]; struct point { int id; int x; }post[N<<2]; int cmp1(point a,point b) { return a.x<b.x; } int cmp2(point a,point b) { if(a.id==b.id) return a.x<b.x; return a.id>b.id; } void pushup(int u) { tr[u].vis=tr[u<<1].vis&&tr[u<<1|1].vis; } void build(int u,int l,int r) { tr[u]={l,r,0}; if(l==r) return ; int mid=l+r>>1; build(u<<1,l,mid); build(u<<1|1,mid+1,r); } void query(int u,int l,int r) { if(tr[u].vis) return ; if(tr[u].l==l&&tr[u].r==r) { tr[u].vis=1; flag=1; return; } int mid=tr[u].l+tr[u].r>>1; if(r<=mid) query(u<<1,l,r); else if(l>mid) query(u<<1|1,l,r); else { query(u<<1,l,mid); query(u<<1|1,mid+1,r); } pushup(u); } int main() { int t,n; cin>>t; while(t--) { cin>>n; //离散化之前的数据 for(int i=0;i<2*n;i+=2) { cin>>post[i].x>>post[i+1].x; post[i].id=post[i+1].id=i; } //按照离散化之前的数据排序 sort(post,post+2*n,cmp1); //离散化 int tot=0,pre=0; for(int i=0;i<2*n;i++) { //如果和上一个一样 //那么排名也就一样 if(post[i].x==pre) { post[i].x=tot; } //如果不一样,记录当前值 //排名++ else { pre=post[i].x; post[i].x=++tot; } } build(1,1,2*n); //排序,从后往前贴 //id大的在前 sort(post,post+2*n,cmp2); int ans=0; for(int i=0;i<2*n;i+=2) { int l=post[i].x; int r=post[i+1].x; flag=0; query(1,l,r); if(flag) ans++; } cout<<ans<<endl; } return 0; }