和Leo一起做热爱线段树的好孩子HDU1542 Atlantis

版权声明:LeoJAM Presents https://blog.csdn.net/fcb_x/article/details/81943023

扫描线模板题

看来扫描线水平依旧不过硬

本质:求矩形的并

利用扫描线一段一段的扫

实现方式是线段树

注意发现区间是实数问题

离散化

#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
using namespace std;
#define lc (p<<1)
#define rc (p<<1|1)
const int N=2e4+1000;
int n;
double mmp[N<<1];
int cntmmp=0;
int tot=0;
struct Data{
	double l,r,h;
	int val;
}A[N<<1];
int cntdata=0;
bool cmp(Data A,Data B){
	return A.h<B.h;
}
struct Segment_Tree{
	struct Node{
		int lson,rson,addlazy;
		double len;
	}T[N<<2];
	inline void Clear(){
		memset(T,0,sizeof(T));
	}
	inline void PushUp(int p){
		if(T[p].addlazy){
			T[p].len=(mmp[T[p].rson+1]-mmp[T[p].lson]);
		}
		else{
			if(T[p].lson==T[p].rson){
				T[p].len=0;
			}
			else T[p].len=T[lc].len+T[rc].len;
		}
	}
	inline void build(int p,int l,int r){
		T[p].lson=l;
		T[p].rson=r;
		if(l==r){
			T[p].len=T[p].addlazy=0;
			return;
		}
		int mid=(l+r)/2;
		build(lc,l    ,mid);
		build(rc,mid+1,r  );
	}
	inline void Update(int p,int l,int r,int val){
		if(l<=T[p].lson&&T[p].rson<=r){
			T[p].addlazy+=val;
			PushUp(p);
			return;
		}
		int mid=(T[p].lson+T[p].rson)/2;
		if(l<=mid)Update(lc,l,r,val);
		if(mid <r)Update(rc,l,r,val);
		PushUp(p);
	}
}Tree;
int main(){
//	freopen("test.in","r",stdin);
	int Id=0;
	while(~scanf("%d",&n)){
		if(n==0)break;
		Tree.Clear(); 
		cntdata=cntmmp=0;
		tot=0;
		for(int i=1;i<=n;i++){
			double x1,y1,x2,y2;
			scanf("%lf%lf%lf%lf",&x1,&y1,&x2,&y2);
			Data Add,Del;
			Add.l=Del.l=x1;
			Add.r=Del.r=x2;
			Add.h=y1;
			Del.h=y2;
			Add.val=1;
			Del.val=-1;
			A[++cntdata]=Add;
			A[++cntdata]=Del;
			mmp[++cntmmp]=x1;
			mmp[++cntmmp]=x2;
		}
		sort(A+1,A+1+cntdata,cmp);
		sort(mmp+1,mmp+1+cntmmp);
		int len=unique(mmp+1,mmp+1+cntmmp)-mmp-1;
		Tree.build(1,1,len);
		double ans=0;
		for(int i=1;i<=cntdata;i++){
			int l=lower_bound(mmp+1,mmp+1+len,A[i].l)-mmp;
			int r=lower_bound(mmp+1,mmp+1+len,A[i].r)-mmp-1;
			Tree.Update(1,l,r,A[i].val);
			ans+=(A[i+1].h-A[i].h)*Tree.T[1].len;
		}
		printf("Test case #%d\nTotal explored area: %.2lf\n\n",++Id , ans);
	
	}
	
}

猜你喜欢

转载自blog.csdn.net/fcb_x/article/details/81943023