题目:http://poj.org/problem?id=1389 题意:给出n个矩形的左下角和右上角,求出所有矩形面积的并 思路:线段树+离散化+扫描线#include <stdio.h> #include <algorithm> #include <iostream> using namespace std; const int maxn=2000; struct SegMentTree { int l, r, cover, len, sum; }st[maxn<<2]; struct Line { int y_top, y_btm, x; int in; bool operator<(Line l) const { return x<l.x; } }l[maxn+10]; int y[maxn+10], ans, cnt; void BuildTree(int v, int left, int right) { st[v].l=left, st[v].r=right, st[v].cover=0, st[v].len=y[right]-y[left]; if (right-left==1) { st[v].sum=0; return; } int lc=v<<1; int rc=lc+1; int mid=(left+right)>>1; BuildTree(lc, left, mid); BuildTree(rc, mid, right); st[v].sum=st[lc].sum+st[rc].sum; } void Update(int x) { if (st[x].cover>0) st[x].sum=st[x].len; else if (st[x].r-st[x].l>1) st[x].sum=st[x*2].sum+st[x*2+1].sum; else st[x].sum=0; } void Insert(int v, int left, int right) { if (st[v].l==left&&st[v].r==right) st[v].cover++; else { int lc=v<<1; int rc=lc+1; int mid=(st[v].l+st[v].r)>>1; if (right<=mid) Insert(lc, left, right); else if (left>=mid) Insert(rc, left, right); else { Insert(lc, left, mid); Insert(rc, mid, right); } } Update(v); } void Delete(int v, int left, int right) { if (st[v].l==left&&st[v].r==right) st[v].cover--; else { int lc=v<<1; int rc=lc+1; int mid=(st[v].l+st[v].r)>>1; if (right<=mid) Delete(lc, left, right); else if (left>=mid) Delete(rc, left, right); else { Delete(lc, left, mid); Delete(rc, mid, right); } } Update(v); } int GetIndex(int x) { return lower_bound(y, y+cnt, x)-y; } int main() { //freopen("in.txt", "r", stdin); int x1, y1, x2, y2; while (scanf("%d %d %d %d", &x1, &y1, &x2, &y2)==4) { int i=0; if (x1==-1&&y1==-1&&x2==-1&&y2==-1) break; do { l[i*2].y_top=l[i*2+1].y_top=y1; l[i*2].y_btm=l[i*2+1].y_btm=y2; l[i*2].x=x1, l[i*2+1].x=x2; l[i*2].in=1, l[i*2+1].in=0; y[i*2]=y1, y[i*2+1]=y2; i++; }while (scanf("%d %d %d %d", &x1, &y1, &x2, &y2)&&(x1!=-1&&y1!=-1&&x2!=-1&&y2!=-1)); sort(y, y+2*i); sort(l, l+2*i); cnt=0; for (int j=1; j<2*i; j++) { if (y[j]!=y[j-1]) y[cnt++]=y[j-1]; } y[cnt++]=y[2*i-1]; BuildTree(1, 0, cnt-1); ans=0; for (int j=0; j<2*i-1; j++) { if (l[j].in) Insert(1, GetIndex(l[j].y_top), GetIndex(l[j].y_btm)); else Delete(1, GetIndex(l[j].y_top), GetIndex(l[j].y_btm)); ans+=(l[j+1].x-l[j].x)*st[1].sum; } printf("%d\n", ans); } }
PKU 1389 Area of Simple Polygons
最新推荐文章于 2017-12-09 13:36:36 发布