本题有个小trick,就是离散化时相邻两个数相差大于1时,经过离散化就会使得两个数差为1.而在本题中这是有区别的,因为题目中的数表示单位长度,不是一个点,所以要在差大于1的两个数之间插入一个数,然后再离散化。
#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
#define maxn 80005
#define lson l,m,rt<<1
#define rson m+1,r,(rt<<1)|1
int sign[4*maxn+1];
void pushdown(int rt)
{
if( sign[rt] )
{
sign[rt<<1] = sign[rt];
sign[rt<<1|1] = sign[rt];
sign[rt]=0;
}
}
void build(int l,int r,int rt)
{
sign[rt]=0;
if( l==r ) return;
int m=(l+r)/2;
build(lson);
build(rson);
}
void update(int L,int R,int c,int l,int r,int rt)
{
if( L<=l && r<=R )
{
sign[rt]=c;
return;
}
pushdown(rt);
int m=(l+r)/2;
if( L<= m ) update(L,R,c,lson);
if( R>m ) update(L,R,c,rson);
}
int query(int L,int R,int l,int r,int rt)
{
if( L<=l && r<=R )
{
return sign[rt];
}
pushdown(rt);
int m=(l+r)/2;
if( L <= m ) return query(L,R,lson);
if( R>m ) return query(L,R,rson);
}
int main()
{
int _,n,a[80005],i,j,h; int s[20005],e[20005]; int hash[80005];
scanf("%d",&_);
while(_--)
{
scanf("%d",&n); j=1;
memset(hash,0,sizeof(hash));
memset(sign,0,sizeof(sign));
for(i=1;i<=n;i++)
{
scanf("%d%d",s+i,e+i);
a[j++]=s[i]; a[j++]=e[i];
}
sort(a+1,a+j);
h=2;
for(i=2;i<j;i++)
{
if(a[i]!=a[i-1]) a[h++]=a[i];
}
int k; k=h;
for(i=2;i<h;i++)
{
if(a[i]-a[i-1] >= 2)
a[k++]=a[i-1]+1;
}
sort(a+1,a+k);
for(i=1;i<=n;i++)
{
s[i]= lower_bound(a+1,a+k,s[i]) - a + 1;
e[i]= lower_bound(a+1,a+k,e[i]) - a + 1;
}
build(1,k,1); // 这个build可以不要,是多余的,因为它的作用就是memset了sign数组。
for(i=1;i<=n;i++)
{
update(s[i],e[i],i,1,k,1);
}
for(i=1;i<=k;i++)
{
hash[query(i,i,1,k,1)]=1;
}
int ans=0;
for(i=1;i<=n;i++)
ans+=hash[i];
printf("%d\n",ans);
}
return 0;
}