您的位置:首页 > 其它

poj 1177 Picture

2011-02-26 11:08 351 查看
线段树的应用。

主要是用到如下思想:当线段覆盖的总长度发生变化时,肯定遇到了轮廓。

下面博客的代码写的很好,注释很详尽,我笔算了一天,才懂了点这个经典的线段树+离散化+扫描线。
http://www.cppblog.com/abilitytao/archive/2010/07/21/120927.html
#include<iostream>
#include<cstdlib>
#include<cstring>
#include<cstdio>
using namespace std;
#define maxn 10010
struct node
{
int l,r,sum,cover,seg,len;
bool lcover,rcover;
}st[maxn*4];
struct edge
{
int st,ed,x;
bool inout;
}e[maxn];
int index[maxn];
int intcmp(const void *a,const void *b)
{
return *(int *)a- *(int *)b;
}
int edgecmp(const void *a,const void *b)
{
return ((edge *)a)->x - ((edge *)b)->x;
}
int getindex(int *sou,int key,int n)
{
int left=0,right=n,mid;
while(left<=right)
{
mid=(left+right)/2;
if(sou[mid]==key)
return mid;
else if(sou[mid]>key)
right=mid-1;
else
left=mid+1;
}
}
void build(int l,int r,int i)
{
st[i].l=l;
st[i].r=r;
st[i].sum=st[i].seg=st[i].cover=0;
st[i].len=index[r]-index[l];
st[i].lcover=st[i].rcover=false;
if(r-l==1)
return ;
int mid=(l+r)/2;
build(l,mid,2*i);
build(mid,r,2*i+1);
}
void getlen(int i)
{
if(st[i].cover)
st[i].sum=st[i].len;
else if(st[i].r-st[i].l>1)
st[i].sum=st[2*i].sum+st[2*i+1].sum;
else
st[i].sum=0;
}
void getseg(int i)
{
if(st[i].cover>0)
{
st[i].lcover=st[i].rcover=true;
st[i].seg=1;
}
else if(st[i].r-st[i].l>1)
{
st[i].lcover=st[2*i].lcover;
st[i].rcover=st[2*i+1].rcover;
st[i].seg=st[2*i+1].seg+st[2*i].seg-st[2*i+1].lcover*st[2*i].rcover;
}
else
{
st[i].lcover=st[i].rcover=false;
st[i].seg=0;
}
}
void update(int l,int r,int i,bool inout)
{
if(st[i].l==l&&st[i].r==r)
{
if(inout)
st[i].cover++;
else
st[i].cover--;
}
else
{
int mid=(st[i].l+st[i].r)/2;
if(r<=mid)
update(l,r,2*i,inout);
else if(l>=mid)
update(l,r,2*i+1,inout);
else
{
update(l,mid,2*i,inout);
update(mid,r,2*i+1,inout);
}
}
getlen(i);
getseg(i);
}
int main()
{
int n,x1,y1,x2,y2,i,cnt=0,l,r;
scanf("%d",&n);
for(i=0;i<n;i++)
{
scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
index[2*i]=y1;
index[2*i+1]=y2;
e[2*i].st=e[2*i+1].st=y1;
e[2*i].ed=e[2*i+1].ed=y2;
e[2*i].inout=1;
e[2*i].x=x1;
e[2*i+1].inout=0;
e[2*i+1].x=x2;
}
qsort(e,2*n,sizeof(e[0]),edgecmp);
qsort(index,2*n,sizeof(index[0]),intcmp);
for(i=1;i<2*n;i++)
if(index[i]!=index[cnt])
index[++cnt]=index[i];
build(0,cnt,1);
int ans=0,lsum=0;
for(i=0;i<2*n-1;i++)
{
l=getindex(index,e[i].st,cnt);
r=getindex(index,e[i].ed,cnt);
update(l,r,1,e[i].inout);
ans+=abs(st[1].sum-lsum);
ans+=st[1].seg*2*(e[i+1].x-e[i].x);
lsum=st[1].sum;
}
l=getindex(index,e[2*n-1].st,cnt);
r=getindex(index,e[2*n-1].ed,cnt);
update(l,r,1,0);
ans+=abs(st[1].sum-lsum);
printf("%d/n",ans);
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: