Time Limit: 1000MS | Memory Limit: 65536K | |
Total Submissions: 3257 | Accepted: 1678 |
Description
Input
Output
Sample Input
0 0 4 4 1 1 5 2 1 1 2 5 -1 -1 -1 -1 0 0 2 2 1 1 3 3 2 2 4 4 -1 -1 -1 -1 -1 -1 -1 -1
Sample Output
18 10
Source
#include<stdio.h> #include<string.h> #include<algorithm> using namespace std; #define typeH int //高度的类型 #define MID(l,r) ((l+r)>>1) const int MAXN = 50005; struct Tree { int len,cover; //每个区间范围内的点出现次数>0的个数,每个点覆盖的次数 }root[MAXN*4]; struct RectEdg { typeH H; //每条边距X轴的高度 int l,r,cnt; //线段的真实左节点与右节点,cnt=1表示矩形的下边,cnt=0则为上边 }edg[MAXN*2]; int W[MAXN*2]; //宽度点的离散化点集 void builde(int l,int r,int k) { root[k].len=root[k].cover=0; if(l==r-1)return ; int m=MID(l,r); builde(l,m,k<<1); builde(m,r,k<<1|1); } void getlen(int l,int r,int k) { if(root[k].cover>0) root[k].len = W[r]-W[l]; else if(l==r-1) root[k].len=0; else root[k].len = root[k<<1].len + root[k<<1|1].len; } void update(int l,int r,int k,int L,int R,int cnt) { if(L<=W[l]&&W[r]<=R) { root[k].cover += cnt ; getlen(l,r,k); return ; } if(l==r-1) return ; int m=MID(l,r); if(L<=W[m]) update( l,m,k<<1 , L , R , cnt); if(W[m]<R) update( m,r,k<<1|1 , L , R , cnt); getlen(l,r,k); } void getUnique(int& maxlen) //线段树的宽度离散化,去重 { int k=maxlen; maxlen=1; sort(W+1,W+1+k); for(int i=2; i<=k; i++) if(W[maxlen]!=W[i]) W[++maxlen]=W[i]; } bool cmp(RectEdg aa, RectEdg bb)//边高按从小到大排序 { return aa.H<bb.H; } int maxlen,tot; //线段树的长度 与 总边数 void addRectEdg(int h1,int h2,int l,int r) { edg[tot].l=l; edg[tot].r=r; edg[tot].H=h1; edg[tot++].cnt=1; //矩形的下边 edg[tot].l=l; edg[tot].r=r; edg[tot].H=h2; edg[tot++].cnt=-1; //矩形的上边 W[++maxlen]=l; W[++maxlen]=r; } int main() { int x1,y1,x2,y2 ; while(scanf("%d%d%d%d",&x1,&y1,&x2,&y2)>0) { if(x1+y1+x2+y2==-4) break; maxlen=1; tot=0; if(x1<x2&&y1<y2) addRectEdg(y1 , y2 , x1 , x2); if(x2>maxlen)maxlen=x2; while(1) { scanf("%d%d%d%d",&x1,&y1,&x2,&y2); if(x1+y1+x2+y2==-4) break; if(x1<x2&&y1<y2) addRectEdg(y1 , y2 , x1 , x2); if(x2>maxlen)maxlen=x2; } sort(edg,edg+tot,cmp); getUnique(maxlen); builde(1 , maxlen , 1); long long area=0; for(int i=0; i<tot-1; i++) { int L,R; L=edg[i].l ; R=edg[i].r ; update(1 , maxlen , 1 , L , R , edg[i].cnt); area += (edg[i+1].H-edg[i].H)*root[1].len; // printf("%d--%d len=%d , area = %d\n",W[L],W[R],root[1].len,area); } printf("%lld\n",area); } }
版权声明:本文为博主原创文章,未经博主允许不得转载。
POJ 1389 Area of Simple Polygons(面积合并,线段树+离散化)
原文地址:http://blog.csdn.net/u010372095/article/details/46959069