您的位置:首页 > 其它

poj 2528 Mayor's posters 正确离散化

2011-03-20 11:51 621 查看
理解线段树离散化的好题

关于这个题离散化的问题,在discuss里有人说测试数据是错的,如果按照一般的离散化的方法去写有种数据不能过

1 10

1 5

8 10

如果像我下面的代码那样写离散化的结果

1 4

1 2

3 4

很明显6-7这条线段在离散化时被消除了

如果想得到正确的结果其实只用在离散化时修改一下就可以了。

如果这两条线段的两个端点是相邻的,cnt++

不相邻cnt+=2;

正确的离散化代码:

for(i=1;i<2*n;i++)
{
if(L[i].s!=L[i-1].s)
{
if(L[i-1].s+1==L[i].s)
cnt+=1;
else
cnt+=2;
}
if(L[i].flag)
p[L[i].num].x=cnt;
else
p[L[i].num].y=cnt;
}


下面的代码shi

/*
* File:   main.cpp
* Author: Mi
*
* Created on 2011年3月13日, 上午11:14
* 关于线段树离散化看了很多资料都没看懂,现在找了个题来做做,发现离散化原来很简单
* 离散化就是把一些无用的区间进行压缩,而不改变区间的覆盖关系,从而达到节省空间的目的
* 用一个结构体p
来保存节点,line保存线段的信息,line[i].s表示端点,line[i].num,表示属于那条线段
* 然后对line按端点从小到大排序,如果有m个不同的端点,则线段范围就是[1,m]
*/
#include <cstdlib>
#include <stdio.h>
#include <string.h>
#include <algorithm>
#define N 40005
using namespace std;
/*
*
*/
int flag
,ans;
struct tree
{
int l,r,c;
}T[N*3];
struct node
{
int x,y;
}p
;
struct line
{
int s,num;
}L[N*3];
void build(int l,int r,int root)
{
T[root].l=l,T[root].r=r;
T[root].c=0;
if(l==r)
return ;
int mid=(l+r)>>1;
build(l,mid,root<<1);
build(mid+1,r,root<<1|1);
}
void modify(int l,int r,int root,int c)
{
if(T[root].l==l&&T[root].r==r)
{
T[root].c=c;
return ;
}
if(T[root].c&&T[root].c!=c)
{
T[root<<1].c=T[root].c;
T[root<<1|1].c=T[root].c;
T[root].c=0;
}
int mid=(T[root].l+T[root].r)>>1;
if(r<=mid)
modify(l,r,root<<1,c);
else if(l>mid)
modify(l,r,root<<1|1,c);
else
{
modify(l,mid,root<<1,c);
modify(mid+1,r,root<<1|1,c);
}
}
void query(int root)
{
if(T[root].c)
{
if(!flag[T[root].c])
{
flag[T[root].c]=1;
ans++;
}
return ;
}
query(root<<1);
query(root<<1|1);
}
bool cmp(line x,line y)
{
return x.s<y.s;
}
int main(int argc, char** argv)
{
int t,n,i;
scanf("%d",&t);
while(t--)
{
scanf("%d",&n);
memset(flag,0,sizeof(flag));
for(i=0;i<n;i++)
{
scanf("%d%d",&p[i].x,&p[i].y);
L[2*i].s=p[i].x,L[2*i].num=-(i+1),L[i*2+1].s=p[i].y,L[i*2+1].num=i+1;
}
sort(L,L+2*n,cmp);
int cnt=1,temp=L[0].s;
for(i=0;i<2*n;i++)
{
if(L[i].s!=temp)
{
cnt++;
temp=L[i].s;
}
if(L[i].num<0)
p[-L[i].num-1].x=cnt;
else
p[L[i].num-1].y=cnt;
}
build(1,cnt,1);
for(i=0;i<n;i++)
modify(p[i].x,p[i].y,1,i+1);
ans=0;
query(1);
printf("%d/n",ans);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: