这个题目很多网上的解题报告都是错的,
但是交了可以AC。不过我还是仔细检查了一下,最后自己写了二天,很悲剧。
第一次是因为最后的查询区间的(1,k) 写成了(1,n)导致一直检查不出错误,但是从过程中又得到的是正确答案。
第二次是因为离散化,反正是相当的蛋疼。
做线段树已经快一个星期了,感觉自己的决心越来越不够了。
有点失望,害怕……
马上就是区域赛的网络赛了,
虽然自己的实力还欠火候,但是至少这也是自己一个追求……
好了,下面代码:
#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
#define M 50000 //测试过必须要开到5W才能过,不理解为什么。
#define mid (l+r)>>1
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
int turn[M<<2],color[M<<2],x[M],y[M],n,k,ans;
bool use[M];
int binsch(int p){
int l=0,r=k-1,m;
while(l<=r){
m=mid;
if(turn[m] == p)
return m+1;
if(turn[m]<p)
l=m+1;
else
r=m-1;
}
return -1;
}
void init(){
int i,j=1,s=0;
ans=0;
scanf("%d",&n);
for(i=0;i<n;i++){
scanf("%d %d",&x[i],&y[i]);
turn[s++]=x[i],turn[s++]=y[i];
turn[s++]= (x[i] +y[i])>>1; //离散化过程可能会出现异常,所以在中间添加一个中位数,也可以多添加几个。
//此离散化过了disuss里面的全部数据。
}
sort(turn,turn+s);
k=1;
for(j=1;j<s;j++){
if(turn[j] != turn[j-1])
turn[k++]=turn[j];
}
memset(color,0,sizeof(color));
}
void pushsub(int rt){
if(color[rt]){
color[rt<<1] = color[rt<<1|1] = color[rt];
color[rt] = 0;
}
}
void change(int c,int L,int R,int l,int r,int rt){
if(L<=l && r<=R){
color[rt] =c;
return ;
}
if(l == r) return ;
pushsub(rt);
int m = mid;
if(L<=m)
change(c,L,R,lson);
if(m<R)
change(c,L,R,rson);
}
void updata(){
for(int i=0;i<n;i++){
change((i+1),binsch(x[i]),binsch(y[i]),1,k,1);
}
}
void count(int l,int r,int rt){
if(color[rt]&&!use[color[rt]]){
ans++;
use[color[rt]]=true;
return ;
}
if(l == r) return ;
int m = mid;
count(lson);
count(rson);
}
int main(){
int cas;
scanf("%d",&cas);
while(cas--){
init();
updata();
memset(use,false,sizeof(use));
count(1,k,1);
cout<<ans<<endl;
}
return 0;
}