首先应该对该【0,10000000】进行离散化
即先将点集进行排序,然后从小到大缩小其中的间距,使得最后点数不会超过2*n
然后就是线段树操作
只需进行染色,然后最后用nlgn进行一个个查询颜色记录即可
#include<cstdio>
#include<cstring>
int color[20005*4],a[20005],p[20005],l[10005],r[10005],pd[10005],i,j,k,n,t,length;
void qs(int x,int y){
int i=x,j=y,k=a[(x+y)/2],t;
do{
while(a[i]<k) i++;
while(a[j]>k) j--;
if(i<=j){
t=a[i];a[i]=a[j];a[j]=t;
t=p[i];p[i]=p[j];p[j]=t;
i++;j--;
}
}while(i<j);
if(i<y) qs(i,y);
if(x<j) qs(x,j);
}
void build(int x,int y,int rt){
color[rt]=0;
if(x>=y) return;
int m=(x+y)/2;
build(x,m,2*rt);
build(m+1,y,2*rt+1);
}
void PushDown(int rt){
if(color[rt]!=0){
color[rt*2]=color[rt*2+1]=color[rt];
color[rt]=0;
}
}
void update(int x,int y,int rt){
if(l[k]<=x&&r[k]>=y){
color[rt]=k;
return;
}
PushDown(rt);
int m=(x+y)/2;
if(l[k]<=m) update(x,m,rt*2);
if(r[k]>m) update(m+1,y,rt*2+1);
}
int query(int x,int y,int rt){
if(color[rt]!=0){
if(!pd[color[rt]]) {
pd[color[rt]]=1;
return 1;
}
else return 0;
}
if(x==y) return 0;
int m=(x+y)/2;
return(query(x,m,rt*2)+query(m+1,y,rt*2+1));
}
int main()
{
scanf("%d",&t);
while(t--){
memset(pd,0,sizeof(pd));
scanf("%d",&n);
for(i=1;i<=n;i++){
scanf("%d%d",&a[2*i-1],&a[2*i]);
p[2*i-1]=2*i-1;
p[2*i]=2*i;
}
qs(1,2*n);
length=1;
for(i=1;i<=2*n;i++){
if(p[i]%2==0)
r[p[i]/2]=length;
else
l[(p[i]+1)/2]=length;
if(a[i]!=a[i+1]) length++;
}
build(1,length,1);
for(k=1;k<=n;k++)
update(1,length,1);
printf("%d\n",query(1,length,1));
}
return 0;
}