HDU 3265 - Posters

15 篇文章 0 订阅

 

题目地址: http://acm.hdu.edu.cn/showproblem.php?pid=3265

 

方法 : 线段树 + 扫描线

 

昨晚做了哈,想用个高效的方法(每个“回”字只用两次),貌似想搓了,不得已重新回到暴力(每个“回”字分成4份)。

 

另外,因为利用的是点化区间的方法。RE了一次,原因是没判断 if(p[i].y2>p[i].y1) , 题目中两者是有可能相等的。

   

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring> 
#define ll (v<<1)
#define rr (v<<1|1)
#define tmid ((l+r)>>1)
 
using namespace std;

const int maxn=50000;

struct Node{
	int x,y1,y2,f;
	Node(){}
	Node(int xx,int yy1,int yy2,int ff){
		x=xx,y1=yy1,y2=yy2,f=ff;
	}
}p[8*maxn+100];

int cmp(Node a,Node b){
	return a.x!=b.x?a.x<b.x:a.f>b.f;
}

int rec[4*maxn+100],len[4*maxn+100];

void update(int val,int L,int R,int l,int r,int v){
	if(L<=l && r<=R) rec[v]+=val;
	else{
		if(L<=tmid) update(val,L,R,l,tmid,ll);
		if(R>tmid) update(val,L,R,tmid+1,r,rr);  
	}
	if(rec[v]) len[v]=r-l+1;
	else if(l==r) len[v]=0;
	else len[v]=len[ll]+len[rr];
}

int main(){
	int x1,x2,y1,y2,x3,x4,y3,y4;
	int n,cntp,i;
	__int64 sum;
	while(~scanf("%d",&n),n){
		cntp=0;
		while(n--){
			scanf("%d%d%d%d%d%d%d%d",&x1,&y1,&x2,&y2,&x3,&y3,&x4,&y4);
			p[cntp++]=Node(x1,y1,y2,1);
			p[cntp++]=Node(x3,y1,y2,-1);
			p[cntp++]=Node(x4,y1,y2,1);
			p[cntp++]=Node(x2,y1,y2,-1);
			p[cntp++]=Node(x3,y1,y3,1);
			p[cntp++]=Node(x4,y1,y3,-1);
			p[cntp++]=Node(x3,y4,y2,1);
			p[cntp++]=Node(x4,y4,y2,-1);
		}
		sort(p,p+cntp,cmp);
		memset(rec,0,sizeof(rec));
		memset(len,0,sizeof(len));
		sum=0;
		for(i=0;i<cntp-1;i++){
			if(p[i].y2>p[i].y1)update(p[i].f,p[i].y1,p[i].y2-1,0,maxn-1,1);
			sum+=(__int64)len[1]*(p[i+1].x-p[i].x); 
		}
		printf("%I64d\n",sum);
	}
	return 0;
} 


 

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值