poj 1177 Picture
2011-02-26 11:08
351 查看
线段树的应用。
主要是用到如下思想:当线段覆盖的总长度发生变化时,肯定遇到了轮廓。
下面博客的代码写的很好,注释很详尽,我笔算了一天,才懂了点这个经典的线段树+离散化+扫描线。
http://www.cppblog.com/abilitytao/archive/2010/07/21/120927.html
主要是用到如下思想:当线段覆盖的总长度发生变化时,肯定遇到了轮廓。
下面博客的代码写的很好,注释很详尽,我笔算了一天,才懂了点这个经典的线段树+离散化+扫描线。
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; }
相关文章推荐
- POJ 1177 Picture(线段树+离散化 求周长)
- hdu 1828(poj 1177)Picture(线段树+扫描线)(轮廓线)
- POJ-1177-Picture(线段树+Y方向离散化+读取perimeterのX方向的扫描)
- poj 1177 Picture (线段树 扫描线 离散化 矩形周长并)
- POJ 1177 Picture
- POJ 1177 Picture
- POJ 1177 Picture 求多个矩形周长 -
- hdu 1828(poj 1177)Picture(线段树+扫描线)(轮廓线)
- POJ - 1177 Picture (线段树 + 扫描线)
- poj 1177 & hdu 1828 Picture 线段树 扫描线求矩形周长并
- POJ-1177 Picture 矩形覆盖周长并
- POJ-1177-Picture(线段树+扫描线+离散化)[矩形周长并]
- Picture - POJ 1177 扫描线 矩阵合并的周长
- POJ 1177 Picture(求周长并)
- poj-1177 Picture(矩形周长并,线段树+扫描线)
- poj1177 Picture 离散 注意排序
- 【转】POJ 1177 Picture(1)
- hdu 1828(poj 1177)Picture(线段树+扫描线)(轮廓线)
- POJ 1177 Picture & hdu 1828 Picture(扫描线)
- POJ 1177/HDU 1828 picture 线段树+离散化+扫描线 轮廓周长计算