POJ 1389 Area of Simple Polygons 线段树求矩形面积

来源:http://poj.org/problem?id=1389

题意:给一些矩形,让求这些矩形的面积。矩形是给出的左下角和右下角的坐标,都是正整数。

思路:简单的线段树题目,就是求矩形面积。因为都是整数,而且数据范围不大,因此不需要离散化。

代码:

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <string.h>
using namespace std;

const int N = 50010,M = 1010;
struct tree{
	int lp,rp,len,num;
	int getmid(){
	   return (lp + rp) / 2;
	}
}tt[N * 4];
struct line{
	int lp,rp,cnt,value;
}LL[M * 2];
void built_tree(int lpos,int rpos,int pos){
	tt[pos].lp = lpos;
	tt[pos].rp = rpos;
	tt[pos].len = tt[pos].num = 0;
	if(tt[pos].lp + 1 == tt[pos].rp)
		return;
	int mid = tt[pos].getmid();
	built_tree(lpos,mid,pos*2);
	built_tree(mid,rpos,pos*2+1);
}
bool cmp(line a,line b){
	return a.value > b.value;
}
void getlen(int pos){
	if(tt[pos].num > 0)
		tt[pos].len = tt[pos].rp - tt[pos].lp;
	else if(tt[pos].lp + 1 == tt[pos].rp)
		tt[pos].len = 0;
	else
		tt[pos].len = tt[pos * 2].len + tt[pos * 2 + 1].len;
}
void update(int pos,int id){
	if(tt[pos].lp >= LL[id].lp && tt[pos].rp <= LL[id].rp){
	    tt[pos].num += LL[id].cnt;
		getlen(pos);
		return;
	}
	if(tt[pos].lp + 1 == tt[pos].rp)
		return;
	int mid = tt[pos].getmid();
	if(LL[id].lp >= mid){
	   update(pos * 2 + 1,id);
	}
	else if(LL[id].rp <= mid){
	   update(pos * 2,id);
	}
	else{
	   update(pos * 2,id);
	   update(pos * 2 + 1,id);
	}
	getlen(pos);
}
int main(){
	//freopen("1.txt","r",stdin);
	int a,b,c,d,tot = 0;
	while(scanf("%d%d%d%d",&a,&b,&c,&d) && (a + b + c + d) != -4){
		tot = 0;
	    LL[tot].lp = a; LL[tot].rp = c; LL[tot].value = d; LL[tot++].cnt = 1;
		LL[tot].lp = a; LL[tot].rp = c; LL[tot].value = b; LL[tot++].cnt = -1;
		int x1,y1,x2,y2;
		while(1){
		   scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
		   if(x1 + y1 + x2 + y2 == -4)
			   break;
		   LL[tot].lp = x1; LL[tot].rp = x2; LL[tot].value = y2; LL[tot++].cnt = 1;
		   LL[tot].lp = x1; LL[tot].rp = x2; LL[tot].value = y1; LL[tot++].cnt = -1;
		}
		built_tree(0,N,1);
		sort(LL,LL+tot,cmp);
		update(1,0);
		long long ans = 0;
		for(int i = 1; i < tot; ++i){
		   ans += tt[1].len * (LL[i-1].value - LL[i].value);
		   update(1,i);
		}
		printf("%lld\n",ans);
	}
	return 0;
}


  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值