扫描线

算法————扫描线

1.算法描述

2.coding:

#include<bits/stdc++.h>
#define N 1000005
#define int long long
using namespace std;
int n,tot,ans=0;
int x,y,xx,yy,sl,sr,p;
int nd[N];
struct edge{
	int l,r,h;
	int mark;
	bool operator <(const edge &a) const{
		return h<a.h;
	}
}line[N*2];
struct tree{
	int l,r;
	int sum,len;
	#define l(x) a[x].l
	#define r(x) a[x].r
	#define sum(x) a[x].sum
	#define len(x) a[x].len
}a[N*4];
int ls(int x){return x<<1;}
int rs(int x){return x<<1|1;}
void build(int x,int l,int r){
	l(x)=l,r(x)=r;
	sum(x)=len(x)=0;
	if(l==r)return;
	int mid=(l+r)>>1;
	build(ls(x),l,mid);
	build(rs(x),mid+1,r);
	return;
} 
void pushup(int x){
	if(sum(x))
		len(x)=nd[r(x)+1]-nd[l(x)];
	else
		len(x)=len(ls(x))+len(rs(x));
}
void edit(int x){
	if(nd[r(x)+1]<=sl||sr<=nd[l(x)])
		return;
	if(sl<=nd[l(x)]&&nd[r(x)+1]<=sr){
		sum(x)+=p;
		pushup(x);
		return;
	}
	edit(ls(x));
	edit(rs(x));
	pushup(x);
	return;
}
signed main(){
	scanf("%lld",&n);
	for(int i=1;i<=n;i++){
		scanf("%lld%lld%lld%lld",&x,&y,&xx,&yy);
		nd[2*i-1]=x,nd[2*i]=xx;
		line[2*i-1]=edge{x,xx,y,1};
		line [2*i]=edge{x,xx,yy,-1};
	}
	n<<=1;
	sort(line+1,line+1+n);
	sort(nd+1,nd+1+n);
	tot=unique(nd+1,nd+n+1)-nd-1;
	build(1,1,tot-1);
	for(int i=1;i<n;i++){
		sl=line[i].l,sr=line[i].r,p=line[i].mark;
		edit(1);
		ans+=len(1)*(line[i+1].h-line[i].h);
	}
	printf("%lld\n",ans);
	return 0;
}
posted @ 2022-09-05 21:52  windf_风岚  阅读(34)  评论(0)    收藏  举报
1