题目链接:http://poj.org/problem?id=2528
题目大意:往一面很长的墙上贴海报,最后能看到几张。也就是往这面墙上涂颜色,最后可见多少种不同的颜色。
线段树+离散化。
#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<map>
using namespace std;
inline int input()
{
int ret=0;
char c=getchar();
while(c<'0'||c>'9') c=getchar();
while(c>='0'&&c<='9') ret=ret*10+c-'0',c=getchar();
return ret;
}
#define N 20010
struct Poster
{
int id,s,t;
}p[N/2];
struct node
{
int l,r,id,lazy;
}root[N*4];
map<int,bool>ans;
map<int,int>m;
map<int,int>::iterator it;
int t,n,k;
inline void build(int t,int x,int y)
{
root[t].l=x,root[t].r=y;
root[t].id=root[t].lazy=0;
if(x==y) return;
int mid=(x+y)>>1;
build(t*2,x,mid);
build(t*2+1,mid+1,y);
}
inline void Modefiy(int t,int x,int y,int val)
{
int l=root[t].l,r=root[t].r;
int mid=(l+r)>>1;
if(l==x&&r==y)
{
root[t].id=val;
root[t].lazy=val;
return;
}
if(root[t].lazy!=0)
{
Modefiy(t*2,l,mid,root[t].lazy);
Modefiy(t*2+1,mid+1,r,root[t].lazy);
root[t].lazy=0;
}
if(x<=mid)
Modefiy(t*2,x,min(mid,y),val);
if(y>mid)
Modefiy(t*2+1,max(x,mid+1),y,val);
}
inline void query(int t)
{
int l=root[t].l;
int r=root[t].r;
int mid=(l+r)>>1;
if(l==r)
{
if(root[t].id!=0)
ans[root[t].id]=1;
return;
}
if(root[t].lazy!=0)
{
Modefiy(t*2,l,mid,root[t].lazy);
Modefiy(t*2+1,mid+1,r,root[t].lazy);
root[t].lazy=0;
}
query(t*2);
query(t*2+1);
}
int main()
{
t=input();
while(t--)
{
n=input();
m.clear();
for(int i=1;i<=n;i++)
{
p[i].s=input();
p[i].t=input();
p[i].id=i;
m[p[i].s]=1;
m[p[i].t]=1;
}
k=1;
for(it=m.begin();it!=m.end();it++)
{
m[it->first]=k++;
}
build(1,1,k);
for(int i=1;i<=n;i++)
{
Modefiy(1,m[p[i].s],m[p[i].t],p[i].id);
}
ans.clear();
query(1);
printf("%d\n",ans.size());
}
}