洛谷 P5490 【模板】扫描线

题目描述

题目传送门

分析

存一下板子,注意线段树维护的是左闭右开的区间

代码

#include<cstdio>
#include<algorithm>
#include<cmath>
#include<cstring>
#define rg register
inline int read(){
	rg int x=0,fh=1;
	rg char ch=getchar();
	while(ch<'0' || ch>'9'){
		if(ch=='-') fh=-1;
		ch=getchar();
	}
	while(ch>='0' && ch<='9'){
		x=(x<<1)+(x<<3)+(ch^48);
		ch=getchar();
	}
	return x*fh;
}
const int maxn=1e6+5;
int n,sta[maxn],tp=0,js=0,rk[maxn];
long long ans;
struct jie{
	int val,l,r,op;
	jie(){}
	jie(int aa,int bb,int cc,int dd){
		val=aa,l=bb,r=cc,op=dd;
	}
}b[maxn];
bool cmp(jie aa,jie bb){
	return aa.val<bb.val;
}
struct trr{
	int l,r,cnt,len;
}tr[maxn<<2];
void push_up(int da){
	if(tr[da].cnt) tr[da].len=sta[tr[da].r+1]-sta[tr[da].l];
	else tr[da].len=tr[da<<1].len+tr[da<<1|1].len;
}
void build(int da,int l,int r){
	tr[da].l=l,tr[da].r=r;
	if(tr[da].l==tr[da].r){
		tr[da].cnt=tr[da].len=0;
		return;
	}
	rg int mids=(tr[da].l+tr[da].r)>>1;
	build(da<<1,l,mids);
	build(da<<1|1,mids+1,r);
}
void xg(int da,int l,int r,int val){
	if(tr[da].l>=l && tr[da].r<=r){
		tr[da].cnt+=val;
		push_up(da);
		return;
	}
	rg int mids=(tr[da].l+tr[da].r)>>1;
	if(l<=mids) xg(da<<1,l,r,val);
	if(r>mids) xg(da<<1|1,l,r,val);
	push_up(da);
}
int main(){
	n=read();
	rg int aa,bb,cc,dd;
	for(rg int i=1;i<=n;i++){
		aa=read(),bb=read(),cc=read(),dd=read();
		b[++js]=jie(aa,bb,dd,1);
		b[++js]=jie(cc,bb,dd,-1);
		sta[++tp]=bb;
		sta[++tp]=dd;
	}
	std::sort(sta+1,sta+tp+1);
	tp=std::unique(sta+1,sta+tp+1)-sta-1;
	for(rg int i=1;i<=n*2;i++){
		b[i].l=std::lower_bound(sta+1,sta+1+tp,b[i].l)-sta;
		b[i].r=std::lower_bound(sta+1,sta+1+tp,b[i].r)-sta;
	}
	std::sort(b+1,b+1+n*2,cmp);
	build(1,1,tp);
	b[n*2+1]=b[n*2];
	for(rg int i=1;i<=n*2;i++){
		xg(1,b[i].l,b[i].r-1,b[i].op);
		ans+=1LL*tr[1].len*(b[i+1].val-b[i].val);
	}
	printf("%lld\n",ans);
	return 0;
}
posted @ 2020-10-22 17:50  liuchanglc  阅读(103)  评论(0编辑  收藏  举报