poj 1389 Area of Simple Polygons(线段树做法)

线段树求矩形面积并。和1151一样,只是为了练手~

#include <queue>
#include <stack>
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
#include <limits.h>
#include <string.h>
#include <string>
#include <algorithm>
#define MID(x,y) ((x+y)>>1)
#define L(x) ( x << 1 )
#define R(x) ( x << 1 | 1 )
#define BUG printf("here!!!\n");

using namespace std;

const int MAX = 10100;
struct Sline{ int x,y1,y2,flag;};
struct Tnode{ int l,r,cover,len;};
Tnode node[MAX*4];
Sline l[MAX*2];
int y[MAX];
void add_line(int x1,int y1,int x2,int y2,int &cnt)
{
	l[cnt].x = x1; l[cnt].y1 = y1; l[cnt].y2 = y2;
	l[cnt].flag = 1;
	y[cnt++] = y1;
	l[cnt].x = x2; l[cnt].y1 = y1; l[cnt].y2 = y2;
	l[cnt].flag = -1;
	y[cnt++] = y2;
}
bool cmp(Sline a,Sline b)
{
	return a.x < b.x;
}

void Build(int t,int l,int r)
{
	node[t].l = l; node[t].r = r;
	node[t].cover = 0;
	if( l == r - 1 ) return ;
	int mid = MID(l,r);
	Build(R(t),mid,r);
	Build(L(t),l,mid);
}
void Updata_len(int t)
{
	if( node[t].cover > 0 )
		node[t].len = y[node[t].r] - y[node[t].l];
	else
		if( node[t].l == node[t].r - 1 )
			node[t].len = 0;
		else
			node[t].len = node[R(t)].len + node[L(t)].len;
}

void Updata(int t,Sline p)
{
	if( y[node[t].l] >= p.y1 && y[node[t].r] <= p.y2 )
	{
		node[t].cover += p.flag;
		Updata_len(t);
		return ;
	}
	if( node[t].l == node[t].r - 1 ) return ;
	int mid = MID(node[t].l,node[t].r);
	if( p.y1 <= y[mid] )
		Updata(L(t),p);
	if( p.y2 > y[mid] )
		Updata(R(t),p);
	Updata_len(t);
}
long long solve(int n,int cnt)
{
	Build(1,0,cnt-1);
	Updata(1,l[0]);
	long long ans = 0ll;
	for(int i=1; i<n; i++)
	{
		ans += (l[i].x - l[i-1].x)*node[1].len;
		Updata(1,l[i]);
	}
	return ans;
}
int main()
{
	int lx,ly,rx,ry;
	int n,cnt;
	
	while( ~scanf("%d%d%d%d",&lx,&ly,&rx,&ry) )
	{
		n = cnt = 0;
		if( lx < 0 ) break;
		add_line(lx,ly,rx,ry,cnt);
		while( scanf("%d%d%d%d",&lx,&ly,&rx,&ry) )
		{
			if( lx < 0 ) break;
			add_line(lx,ly,rx,ry,cnt);
		}
		int t = cnt;
		sort(y,y+cnt);
		sort(l,l+cnt,cmp);
		cnt = unique(y,y+cnt) - y;
		long long ans = solve(t,cnt);
		printf("%lld\n",ans);
	}
return 0;
}


你可能感兴趣的:(poj 1389 Area of Simple Polygons(线段树做法))