您的位置:首页 > 其它

POJ 2528 Mayor's Posters

2011-04-15 10:43 537 查看
不难发现,问你有几张海报可见,其实就是问你最后[1,ri]这个区间上被染上了几种颜色

但问题是,ri很大,建这么大的树显然会超时,不过还好,n不是很大,我们可以用离散化的思想来解决

把所有出现的坐标点进行排序,去重,这样,线段树的总长就不会超过2W了,然后把原来每张海报的坐标找到新的对应点,以新的对应点进行区间染色,最后统计一下有几种颜色即可

代码:

#include<iostream>
#include<memory.h>
#include<string>
#include<cstdio>
#include<algorithm>
#include<math.h>
#include<stack>
#include<queue>
using namespace std;
const int MAX=20005;
struct node
{
int l,r;
int color;
}t[MAX*5];
int pos[MAX][2],index[MAX*2];
int n,m;
bool hash[10001];
void build(int ll,int rr,int n)
{
t
.l=ll;
t
.r=rr;
if(ll==rr)
{
t
.color=0;
return;
}
int mid=(ll+rr)/2;
build(ll,mid,n*2);
build(mid+1,rr,n*2+1);
t
.color=0;
}
int find(int x)
{
int l=0,r=m,mid,ans;
//cout<<r<<endl;
while(l<=r)
{
mid=(l+r)/2;
if(index[mid]==x)
{
return mid+1;
}
if(index[mid]<x)
l=mid+1;
else
r=mid-1;
}
}
void update(int ll,int rr,int n,int c)
{
//cout<<"n="<<n<<endl;
if(t
.l==ll&&t
.r==rr)
{
t
.color=c;
return;
}
if(t
.color!=-1)
t[n*2].color=t[n*2+1].color=t
.color;
t
.color=-1;
int mid=(t
.l+t
.r)/2;
if(mid>=rr)
update(ll,rr,n*2,c);
else if(mid<ll)
update(ll,rr,n*2+1,c);
else
{
update(ll,mid,n*2,c);
update(mid+1,rr,n*2+1,c);
}
}
void query(int ll,int rr,int n)
{
if(t
.l==ll&&t
.r==rr&&t
.color!=-1)
{
hash[t
.color]=true;
return;
}
int mid=(t
.l+t
.r)/2;
if(mid>=rr)
query(ll,rr,n*2);
else if(mid<ll)
query(ll,rr,n*2+1);
else
{
query(ll,mid,n*2);
query(mid+1,rr,n*2+1);
}
}
int main()
{
int i,j,k,T;
scanf("%d",&T);
while(T--)
{
memset(hash,0,sizeof(hash));
scanf("%d",&n);
for(k=0;k<n;k++)
{
scanf("%d%d",&pos[k][0],&pos[k][1]);
index[k]=pos[k][0];
index[k+n]=pos[k][1];
}
sort(index,index+n*2);
for(i=0,m=0;i<n*2;i++)
{
if(i==0||index[i]!=index[i-1])
{
index[m++]=index[i];
}
}
build(1,m,1);
//cout<<t[4].l<<endl;
for(k=0;k<n;k++)
{
i=find(pos[k][0]);
j=find(pos[k][1]);
update(i,j,1,k+1);
}
//cout<<"yes"<<endl;
query(1,m,1);
int ans=0;
for(i=1;i<=n;i++)
if(hash[i])
ans++;
printf("%d/n",ans);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: