| 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