#include<cstdio>
#include<cstdlib>
#include<cstring>
int seq[10010][2],ans;
bool visit[10010];
struct Line{
int begin;
int num;//表示其为第几张海报的首尾,首位负,尾为正
}line[20010];
struct Tree{
int s;
int t;
int c;
}tree[80010];
int cmp(const void * a,const void *b){
struct Line *aa=(struct Line *) a;
struct Line *bb=(struct Line *) b;
return aa->begin-bb->begin;
}
void build(int s,int t,int id){
tree[id].s=s;
tree[id].t=t;
tree[id].c=0;
if(s!=t){
int mid=(tree[id].s+tree[id].t)>>1;
build(s,mid,id*2);
build(mid+1,t,id*2+1);
}
}
void insert(int s,int t,int id,int colour){
if(tree[id].s==s && tree[id].t==t){
tree[id].c=colour;
return ;
}//否则的话从s到t的线段一定在tree[id]所表示的线段之内
if(tree[id].c>0 && tree[id].c!=colour){
tree[id*2].c=tree[id].c;
tree[id*2+1].c=tree[id].c;
tree[id].c=0;
}
int mid=(tree[id].s+tree[id].t)>>1;
if(mid<s)
insert(s,t,id*2+1,colour);
else if(mid>=t)
insert(s,t,id*2,colour);
else{
insert(s,mid,id*2,colour);
insert(mid+1,t,id*2+1,colour);
}
}
void search(int id){
if(tree[id].c!=0){
if(visit[tree[id].c]==false){
ans++;
visit[tree[id].c]=true;
}
return;
}
if(tree[id].s!=tree[id].t){
search(id*2);
search(id*2+1);
}
}
int main(){
int n,i,t,T;
scanf("%d",&T);
for(t=1;t<=T;t++){
scanf("%d",&n);
for(i=1;i<=n;i++){
scanf("%d %d",&seq[i][0],&seq[i][1]);
line[2*i-1].begin=seq[i][0];
line[2*i-1].num=-i;
line[2*i].begin=seq[i][1];
line[2*i].num=i;
}
qsort(&line[1],2*n,sizeof(line[1]),cmp);
int temp=line[1].begin,tp=1;
for(i=1;i<=2*n;i++){
if(line[i].begin!=temp){
tp++;
temp=line[i].begin;
}
if(line[i].num<0)
seq[-line[i].num][0]=tp;
else
seq[line[i].num][1]=tp;
}//离散化
build(1,tp,1);
for(i=1;i<=n;i++){
insert(seq[i][0],seq[i][1],1,i);
}
ans=0;
memset(visit,false,sizeof(visit));
search(1);
printf("%d\n",ans);
}
}
poj 2528 Mayor's posters 线段树+离散化
最新推荐文章于 2021-10-24 23:33:10 发布