扫描线模板0pts,求助!!
查看原帖
扫描线模板0pts,求助!!
421265
eastcloud楼主2022/8/23 18:38

rt,找了半天也跟题解比对了一下,思路都是一样的,从左往右扫,用线段树处理,线段树的l,r代表的是离散化后的区间而非端点,调了半天真的找不到了awa

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<map>
#define ll long long
using namespace std;
map<ll,ll> t;
struct Node{
	ll x,y1,y2,k;
}l[1200001];
bool cmp(Node x,Node y){
	return x.x<y.x;
}
ll num[1200001],hash[1200001];
struct seg{
	ll cnt,len,sum;
	ll l,r;
}a[1200001];
void build(ll x,ll l,ll r){
	a[x].l=l;
	a[x].r=r;
	a[x].sum=num[r+1]-num[l];
	a[x].cnt=a[x].len=0;
	ll mid=(l+r)>>1;
	if(l==r) return;
	build(x*2,l,mid);
	build(x*2+1,mid+1,r);
}
void push_up(ll x){
	if(a[x].cnt) a[x].len=a[x].sum;
	else a[x].len=a[x*2].len+a[x*2+1].len;
}
void change(ll x,ll l,ll r,ll k){
	if(a[x].l>=l && a[x].r<=r){
		a[x].cnt+=k;
		push_up(x);
		return;
	}
	ll mid=(a[x].l+a[x].r)>>1;
	if(l<=mid)change(x*2,l,mid,k);
	if(r>mid)change(x*2+1,mid+1,r,k);
	push_up(x);
}
int main(){
	ll n;
	ll tot=0,m=0;
	cin>>n;
	ll x1,y1,x2,y2;
	for(ll i=1;i<=n;i++){
		cin>>x1>>y1>>x2>>y2;
		l[++tot].x=x1;l[tot].y1=y2;l[tot].y2=y1;l[tot].k=1;
		l[++tot].x=x2;l[tot].y1=y2;l[tot].y2=y1;l[tot].k=-1;
		num[++m]=y1;num[++m]=y2;
	}
	sort(l+1,l+tot+1,cmp);
	sort(num+1,num+m+1);
	m=unique(num+1,num+m+1)-num-1;
	build(1,1,m-1);
	for(ll i=1;i<=m;i++)t[num[i]]=i;
	ll ans=0;
	for(ll i=1;i<tot;i++){
		change(1,t[l[i].y2],t[l[i].y1]-1,l[i].k);
		ans+=a[1].len*(l[i+1].x-l[i].x);
	}
	cout<<ans;
}
2022/8/23 18:38
加载中...