站外题(扫描线模板)求助
查看原帖
站外题(扫描线模板)求助
544571
Locix_Elaina_Celome楼主2022/12/30 21:44

题面:

代码:

#include<iostream>
#include<stdio.h>
#include<algorithm>
#include<string.h>
#define INL inline
#define REG register
#define LL long long
#define MMx(x,y) (x<y?y:x)
#define MMn(x,y) (x<y?x:y)
#define Abs(x) ((x)<0?(-(x)):(x))
#define lb(x) ((x)&(-(x)))
#define Start 1
#define End -1
using namespace std;
INL int max(REG int a,REG int b) {
	return MMx(a,b);
}
INL int min(REG int a,REG int b) {
	return MMn(a,b);
}
INL void read(REG int& x) {
	x=0;
	REG char c=getchar();
	REG int fh=1;
	while(!isdigit(c))
		fh=-1,c=getchar();
	while(isdigit(c))
		x=x*10+(c^48),c=getchar();
	x*=fh;
}
void write(REG int x) {
	if(x<0)
		putchar('-'),x=~x+1;
	if(x>9)
		write(x/10);
	putchar(x%10+'0');
	return;
}
struct E {
	double x,y1,y2;
	int Type;
	INL bool operator < (const E& oth) const {
		return x<oth.x;
	}
};
E e[100005];
int a[500005];
int n,m;
LL Sum[500005];
LL lazy[2000005];
double y[100005];

double lleft[100005];
double rright[100005];
double len[100005];
int cover[100005];
int L[100005];
int R[100005];

void build(int now,int l,int r) {
//	cout<<now<<':'<<l<<','<<r<<endl;;
	lleft[now]=y[l];
	L[now]=l;
	R[now]=r;
	rright[now]=y[r];
//	cout<<y[l]<<','<<y[r]<<endl;
	len[now]=0;
	cover[now]=0;
	if(l == r-1) return;
	int mid=(l+r)>>1;
	build(now<<1,l,mid);
	build((now<<1),mid,r);
}

INL void add(int now,E edge) {
//	cout<<now<<"::"<<edge.y1<<','<<lleft[now]<<';'<<edge.y2<<','<<rright[now]<<endl;
	if(edge.y1 == lleft[now]&&edge.y2 == rright[now]) {
		cover[now]+=edge.Type;
//		cout<<now<<"::"<<l<<','<<r<<":::"<<edge.y1<<","<<edge.y2<<endl;
	} else if (edge.y2 <= rright[now<<1]) {//在左子树中找(包含完整区间)
//		cout<<"++";
		add(now<<1,edge);
	} else if (edge.y1 >= lleft[now<<1|1]) { //在右子树中找(包含完整区间)。
//		cout<<"--";
		add(now<<1|1,edge);
	} else {
//		cout<<"**";
		E temp;
		temp = edge;
		temp.y2 = rright[now<<1];
		add(now<<1,temp);
		temp = edge;
		temp.y1 = lleft[now<<1|1];
		add(now<<1+1,temp);
	}
	if (cover[now] > 0){
		len[now] = rright[now] -lleft[now];
//		cout<<now<<"!@::"<<rright[now]<<','<<lleft[now]<<endl;;
	}
	else if (cover[now] == 0 && R[now]-L[now] == 1) len[now] = 0;
	else len[now] = len[now<<1] + len[(now<<1)+1];
}
signed main() {
	while(1) {
		scanf("%d",&n);
		if(n == 0)return 0;
		for(int i=1; i<=n; i++) {
			scanf("%lf%lf",&e[i].x,&e[i].y1);
			scanf("%lf%lf",&e[i+n].x,&e[i+n].y2);
			e[i].y2=e[i+n].y2;
			e[i+n].y1=e[i].y1;
			e[i].Type=Start;
			e[i+n].Type=End;
			y[i]=e[i].y2;
			y[i+n]=e[i].y1;
		}
//		cout<<y[1]<<"+++++++\n";
		sort(e+1,e+(n<<1)+1);
		sort(y+1,y+(n<<1)+1);
//		for(int i=1;i<=n*2;i++){
//			cout<<y[i]<<',';
//		}
		build(1,1,n<<1);
		double S=0;
		for(int i=1; i<=(n<<1); i++) {
//			cout<<len[1]<<"::";
			S+=len[1]*(e[i].x-e[i-1].x);
			add(1,e[i]);
//			cout<<S<<"+++"<<endl;
		}
		cout<<S<<endl;
	}
	return 0;
}

2022/12/30 21:44
加载中...