线段树很简单,主要是离散化。
#include<stdio.h>
#include<string.h>
#include<algorithm>
#define N 40005
int flag[N],ans;
struct tree
{
int l,r,c;
}T[N*3];
struct node
{
int x,y;
}p[N];
struct line
{
int s,num;
}L[N*3];
void build(int l,int r,int rt)
{
T[rt].l=l;
T[rt].r=r;
T[rt].c=0;
if(l==r)
return ;
int mid=(l+r)>>1;
build(l,mid,rt<<1);
build(mid+1,r,rt<<1|1);
}
void Update(int l,int r,int rt,int c)
{
if(T[rt].l==l&&T[rt].r==r)
{
T[rt].c=c;
return ;
}
if(T[rt].c&&T[rt].c!=c)
{
T[rt<<1].c=T[rt].c;
T[rt<<1|1].c=T[rt].c;
T[rt].c=0;
}
int mid=(T[rt].l+T[rt].r)>>1;
if(r<=mid)
Update(l,r,rt<<1,c);
else if(l>mid)
Update(l,r,rt<<1|1,c);
else
{
Update(l,mid,rt<<1,c);
Update(mid+1,r,rt<<1|1,c);
}
}
void query(int rt)
{
if(T[rt].c)
{
if(!flag[T[rt].c])
{
flag[T[rt].c]=1;
ans++;
}
return ;
}
query(rt<<1);
query(rt<<1|1);
}
bool cmp(line x,line y)
{
return x.s<y.s;
}
int main()
{
int t,n,i;
scanf("%d",&t);
while(t--)
{
scanf("%d",&n);
memset(flag,0,sizeof(flag));
for(i=0;i<n;i++)
{
scanf("%d%d",&p[i].x,&p[i].y);
L[2*i].s=p[i].x;
L[2*i].num=-(i+1);
L[i*2+1].s=p[i].y;
L[i*2+1].num=i+1;
}
std::sort(L,L+2*n,cmp);
int cnt=1,temp=L[0].s;
for(i=0;i<2*n;i++)
{
if(L[i].s!=temp)
{
cnt++;
temp=L[i].s;
}
if(L[i].num<0)
p[-L[i].num-1].x=cnt;
else
p[L[i].num-1].y=cnt;
}
build(1,cnt,1);
for(i=0;i<n;i++)
Update(p[i].x,p[i].y,1,i+1);
ans=0;
query(1);
printf("%d\n",ans);
}
return 0;
}