/* 离散化+线段树 由于 数据的输入最大是 10000000 ,直接用开数组肯点会超,所以要将起离散话, 首先 ,我们存储输入的边,将其离散化,后面的就和一般的线段树一样可。 */#include#include #define N 10040struct node{ int l; int r;}p[N*2];struct color{ int l; int r; int c;}q[N*8];int cmp ( const void *a , const void *b ){return *(int *)a - *(int *)b;}int addre[N*4],sum,m,pos[N*4],vis[N];void build(int x,int l,int r){ q[x].l=l; q[x].r=r; q[x].c=0; if(l==r)return ; int mid=(l+r)/2; build(x*2,l,mid); build(x*2+1,mid+1,r);}int find(int x)//离散化后的查询{ int head=1,tail=m-1; while(head<=tail) { int mid=(head+tail)/2; if(addre[mid]==x)return mid; if(addre[mid] x)tail=mid-1; } return 0;}void change(int x,int l,int r,int color){ if(q[x].l==l&&q[x].r==r) { q[x].c=color; return ; } if(q[x].c!=-1)//下分到子节点 { q[x*2].c=q[x].c; q[x*2+1].c=q[x].c; q[x].c=-1; } int mid=(q[x].l+q[x].r)/2; if(r<=mid)change(x*2,l,r,color); else { if(l>mid)change(x*2+1,l,r,color); else { change(x*2,l,mid,color); change(x*2+1,mid+1,r,color); } }}void Get(int x,int l,int r){ if(q[x].c==0)return ; if(q[x].c!=-1) { if(!vis[q[x].c])//避免重复计算 { vis[q[x].c]=1; sum++; } return ; } int mid=(q[x].l+q[x].r)/2; if(r<=mid)Get(x*2,l,r); else { if(l>mid)Get(x*2+1,l,r); else { Get(x*2,l,mid); Get(x*2+1,mid+1,r); } }}int main(){ int T,n,i; scanf("%d",&T); while(T--) { scanf("%d",&n); int k=1; for(i=1;i<=n;i++) { scanf("%d%d",&p[i].l,&p[i].r); pos[k++]=p[i].l; pos[k++]=p[i].r; } qsort(pos,k,sizeof(pos[0]),cmp); addre[1]=pos[1]; m=2; for(i=1;i<=k;i++) { if(pos[i]!=pos[i-1]) { addre[m++]=pos[i];//离散化,用原来点的下标,来代替点,实现离散化 } } build(1,1,m-1); for(i=1;i<=n;i++) { int l=find(p[i].l);//离散化,用原来点的下标,来代替点,实现离散化 int r=find(p[i].r); change(1,l,r,i); } sum=0; for(i=0;i<=n;i++)vis[i]=0; Get(1,1,m-1); printf("%d\n",sum); }}