扫描线68pts求条
查看原帖
扫描线68pts求条
1164775
Jadonyzx楼主2025/1/5 21:48

思路:扫两遍,分别求横竖边

#include<bits/stdc++.h>
#define int long long
#define maxn 4000005
using namespace std;
int tongx[maxn],totx,n,totline,tongy[maxn],toty,maxx;
unsigned long long ans;bool Merge[maxn<<2];
struct matrix{int l1,r1,l2,r2;}a[maxn];
struct seg{int l,r;unsigned long long len;int tag;}tree[maxn<<2];
struct line{int l,r,tag,y;}tongline[maxn<<2];
inline bool cmp(line aaa,line bbb){return aaa.y<bbb.y;}
void build(int id,int l,int r){
	maxx=max(maxx,id);
	tree[id]=(seg){l,r,0,0};
	if(l==r)return;
	int mid=l+r>>1;
	build(id<<1,l,mid);
	build(id<<1|1,mid+1,r);
}
void pushup(int rt,int op){
	int l=tree[rt].l,r=tree[rt].r;
	if(tree[rt].tag)tree[rt].len=(op==1)?tongx[r+1]-tongx[l]:tongy[r+1]-tongy[l];
	else tree[rt].len=tree[rt<<1].len+tree[rt<<1|1].len;
	return;
}
void modify(int id,int l,int r,int tag,int op){
	if(tree[id].r<l||tree[id].l>r)return;
	if(l<=tree[id].l&&tree[id].r<=r){
		tree[id].tag+=tag;
		pushup(id,op);
		return;
	}	
	modify(id<<1,l,r,tag,op);
	modify(id<<1|1,l,r,tag,op);
	pushup(id,op);
	return;
}
bool chk(line aaa,line bbb){
	if(aaa.y!=bbb.y)return 0;
	if(aaa.l>bbb.r||aaa.r<bbb.l)return 0;
	return 1;
}
signed main(){
	cin>>n;
	for(int i(1);i<=n;++i)cin>>a[i].l1>>a[i].l2>>a[i].r1>>a[i].r2;
	for(int i(1);i<=n;++i){
		tongx[++totx]=a[i].l1;
		tongx[++totx]=a[i].r1;
		tongy[++toty]=a[i].l2;
		tongy[++toty]=a[i].r2;
	}
	sort(tongx+1,tongx+1+totx);totx=unique(tongx+1,tongx+1+totx)-(tongx+1);
	sort(tongy+1,tongy+1+toty);toty=unique(tongy+1,tongy+1+toty)-(tongy+1);
	for(int i(1);i<=n;++i){
		a[i].l1=lower_bound(tongx+1,tongx+1+totx,a[i].l1)-(tongx);
		a[i].r1=lower_bound(tongx+1,tongx+1+totx,a[i].r1)-(tongx);
		a[i].l2=lower_bound(tongy+1,tongy+1+toty,a[i].l2)-(tongy);
		a[i].r2=lower_bound(tongy+1,tongy+1+toty,a[i].r2)-(tongy);
		tongline[++totline]={a[i].l1,a[i].r1,1,a[i].l2};
		tongline[++totline]={a[i].l1,a[i].r1,-1,a[i].r2};
	}
	sort(tongline+1,tongline+1+totline,cmp);build(1,1,totx-1);
	int resans=0;
	for(int i=1;i<=totline;++i){
		if(Merge[i])continue;
		while(i+1<=totline&&chk(tongline[i],tongline[i+1])){
			tongline[i+1].l=min(tongline[i+1].l,tongline[i].l);
			tongline[i+1].r=max(tongline[i+1].r,tongline[i].r);
			Merge[i]=1;i++;
		}
	}
	for(int i=1;i<=totline;++i){
		if(Merge[i])continue;
		modify(1,tongline[i].l,tongline[i].r-1,tongline[i].tag,1);
		int nowans=tree[1].len;
		ans+=abs(nowans-resans);resans=nowans;
	}ans+=tree[1].len;
	totline=0;
	for(int i(1);i<=n;++i){
		tongline[++totline]={a[i].l2,a[i].r2,1,a[i].l1};
		tongline[++totline]={a[i].l2,a[i].r2,-1,a[i].r1};
	}
	for(int i=1;i<=maxx;++i)tree[i].l=tree[i].r=tree[i].len=tree[i].tag=0;
	sort(tongline+1,tongline+1+totline,cmp);build(1,1,toty-1);resans=0;
	memset(Merge,0,sizeof Merge);
	for(int i=1;i<=totline;++i){
		if(Merge[i])continue;
		while(i+1<=totline&&chk(tongline[i],tongline[i+1])){
			tongline[i+1].l=min(tongline[i+1].l,tongline[i].l);
			tongline[i+1].r=max(tongline[i+1].r,tongline[i].r);
			Merge[i]=1;i++;
		}
	}
	for(int i=1;i<=totline;++i){
		if(Merge[i])continue;
		modify(1,tongline[i].l,tongline[i].r-1,tongline[i].tag,0);
		int nowans=tree[1].len;
		ans+=abs(nowans-resans);resans=nowans;
	}ans+=tree[1].len;
	cout<<ans;
	return 0;
}
2025/1/5 21:48
加载中...