题目链接:http://poj.org/problem?id=252
思路:l,r范围很大,需要离散化,离散化时注意排序后如果相邻两个数字则可以赋相邻的值,如果二者之间差大于一这需要赋值相差2,例如1-10为红色,1-2为绿色,9-10为蓝色,正确答案为3.
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
const int N=10005;
int t[N*2],vis[N],tp[N*4],ans,cnt,n;
struct tt
{
int x,y;
}sd[N];
struct node
{
int l,r,c,al;
}d[40010<<2];
int find(int x)
{
int l,r,mid;
l=1;r=cnt-1;
while(l<=r)
{
mid=(l+r)>>1;
if(tp[mid]<x)
l=mid+1;
else if(tp[mid]>x)
r=mid;
else
return mid;
}
}
void pushdown(int rt)
{
if(d[rt].l==d[rt].r)
return;
d[rt<<1].c=d[rt<<1|1].c=d[rt].c;
d[rt<<1].al=d[rt<<1|1].al=1;
d[rt].al=0;
}
void pushup(int rt)
{
if(d[rt].l==d[rt].r)
return ;
d[rt].c=d[rt<<1].c;
d[rt].al=1;
}
void build(int rt,int L,int R)
{
d[rt].l=L;
d[rt].r=R;
d[rt].c=-1;
d[rt].al=1;
//printf("build %d %d %d\n",rt ,d[rt].l,d[rt].r);
if(L==R)
return ;
int mid=(L+R)>>1;
build(rt<<1,L,mid);
build(rt<<1|1,mid+1,R);
}
void updata(int rt,int L,int R,int a)
{
if(L==d[rt].l&&R==d[rt].r)
{
d[rt].c=a;
d[rt].al=1;
return ;
}
if(d[rt].al)
pushdown(rt);
int mid=(d[rt].l+d[rt].r)>>1;
if(R<=mid)
updata(rt<<1,L,R,a);
else if(L>mid)
updata(rt<<1|1,L,R,a);
else
{
updata(rt<<1,L,mid,a);
updata(rt<<1|1,mid+1,R,a);
}
if(d[rt<<1].c==d[rt<<1|1].c&&d[rt<<1].al==1&&d[rt<<1|1].al==1)
pushup(rt);
}
void query(int rt,int L,int R)
{
if(d[rt].al)
{
if(d[rt].l==L&&d[rt].r==R)
{
if(d[rt].c!=-1&&vis[d[rt].c]==0)
{
ans++;
vis[d[rt].c]=1;
}
return ;
}
pushdown(rt);
}
int mid=(d[rt].l+d[rt].r)>>1;
if(R<=mid)
query(rt<<1,L,R);
else if(L>mid)
query(rt<<1|1,L,R);
else
{
query(rt<<1,L,mid);
query(rt<<1|1,mid+1,R);
}
}
int main()
{
int i,cas,tl,tr;
//freopen("in.txt","r",stdin);
scanf("%d",&cas);
while(cas--)
{
scanf("%d",&n);
for(i=0;i<n;i++)
{
scanf("%d%d",&t[i*2],&t[i*2+1]);
sd[i].x=t[i*2];
sd[i].y=t[i*2+1];
}
sort(t,t+n*2);
cnt=1;
tp[cnt++]=t[0];
for(i=1;i<2*n;i++)
{
if(t[i]-t[i-1]>1) tp[cnt++]=t[i]-1;
if(t[i]-t[i-1]>0)
tp[cnt++]=t[i];
}
build(1,1,cnt-1);
for(i=0;i<n;i++)
{
tl=find(sd[i].x);
tr=find(sd[i].y);
//printf("find tl=%d tr=%d\n",tl,tr);
updata(1,tl,tr,i);
}
memset(vis,0,sizeof(vis));
ans=0;
query(1,1,cnt-1);
printf("%d\n",ans);
}
return 0;
}