社区讨论

初一萌妹刚学OI,求调玄关T_T

P5490【模板】扫描线 & 矩形面积并参与者 7已保存回复 8

讨论操作

快速查看讨论及其快照的属性,并进行相关操作。

当前回复
8 条
当前快照
1 份
快照标识符
@mhk77950
此快照首次捕获于
2025/11/04 14:38
4 个月前
此快照最后确认于
2025/11/04 14:38
4 个月前
查看原帖
RT
样例ok,but ALL WA
QWQ
CPP
#include<bits/stdc++.h>
#define int long long
#define x1 x_1
#define x2 x_2
#define y1 y_1
#define y2 y_2
using namespace std;
const int N=2e5+10; 
int n,ans,rev,ls[N<<4],lin[N<<4],len[N<<4],id[N<<4];
struct edge{
	int k,l,r,ml,mr,ops;
}e[N<<4];
bool cmp(edge x,edge y){
	return x.k<y.k;
}
void init(int s,int t,int p){
	if (s==t){
		id[s]=p;
		return ;
	}
	int mid=s+t>>1ll;
	init(s,mid,p<<1ll);
	init(mid+1ll,t,p<<1ll|1ll);
	return ;
}
bool check(int x){
	while (!lin[x]&&x)
		x/=2ll;
	return x!=0ll;
}
void update(int l,int r,int s,int t,int ops,int p){
	int mid=s+t>>1ll;
	if (l<=s&&t<=r)
		lin[p]+=ops;
	else{
		if (l<=mid) update(l,r,s,mid,ops,p<<1ll);
		if (r>mid)  update(l,r,mid+1ll,t,ops,p<<1ll|1ll);
	}
	if (lin[p]>0ll) len[p]=ls[t]-ls[s];
	else{
		len[p]=len[p<<1ll]+len[p<<1ll|1ll];
//		mid mid+1
		if (l<=mid&&mid+1ll<=r&&check(id[mid])&&check(id[mid+1ll]))
			len[p]+=ls[mid+1ll]-ls[mid];
	} 
	return ;
}
signed main(){
	scanf ("%lld",&n);
	
	for (int i=1;i<=n;i++){
		int x1,x2,y1,y2;
		scanf ("%lld%lld%lld%lld",&x1,&y1,&x2,&y2);
		e[i*2ll-1ll]={y1,x1,x2,0ll,0ll,1ll};
		e[i*2ll]={y2,x1,x2,0ll,0ll,-1ll};
		ls[i*2ll-1ll]=x1;
		ls[i*2ll]=x2;
	}
	sort (ls+1ll,ls+2ll*n+1ll);
	int cnt=unique(ls+1ll,ls+2ll*n+1ll)-(ls+1ll);
	for (int i=1;i<=n;i++){
		e[i*2ll-1ll].ml=lower_bound(ls+1ll,ls+cnt+1ll,e[i*2ll-1ll].l)-ls;
		e[i*2ll].ml=lower_bound(ls+1ll,ls+cnt+1ll,e[i*2ll].l)-ls;
		e[i*2ll-1ll].mr=lower_bound(ls+1ll,ls+cnt+1ll,e[i*2ll-1ll].r)-ls;
		e[i*2ll].mr=lower_bound(ls+1ll,ls+cnt+1ll,e[i*2ll].r)-ls;
	}
	sort (e+1ll,e+2ll*n+1ll,cmp);
	init(1ll,cnt,1ll);
	for (int i=1ll;i<=n*2ll;i++){
		ans+=len[1ll]*(e[i].k-rev);
		update(e[i].ml,e[i].mr,1ll,cnt,e[i].ops,1ll);
		rev=e[i].k;
			
	}
	printf ("%lld\n",ans);

	return 0;
}
/*
2
100 100 200 200
150 150 250 255
18000
*/

回复

8 条回复,欢迎继续交流。

正在加载回复...