社区讨论

求助模拟赛题

学术版参与者 5已保存回复 9

讨论操作

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

当前回复
9 条
当前快照
1 份
快照标识符
@mjdzwbsz
此快照首次捕获于
2025/12/20 15:47
3 个月前
此快照最后确认于
2025/12/22 16:45
2 个月前
查看原帖
求 n n 个四边平行于坐标轴的矩形的非重叠面积和。
输入格式 第一行一个正整数 n n。
接下来 n n 行每行四个非负整数 x 1 , y 1 , x 2 , y 2 x 1 ​ ,y 1 ​ ,x 2 ​ ,y 2 ​ ,表示一个矩形的四个端点坐标为 ( x 1 , y 1 ) , ( x 1 , y 2 ) , ( x 2 , y 2 ) , ( x 2 , y 1 ) (x 1 ​ ,y 1 ​ ),(x 1 ​ ,y 2 ​ ),(x 2 ​ ,y 2 ​ ),(x 2 ​ ,y 1 ​ )。
输出格式 一行一个正整数,表示 n n 个矩形的非重叠面积和。
样例 样例 1 输入: 2 0 0 5 5 4 0 7 3 样例 1 输出: 28 样例解析
数据规模 对于 20 % 20% 的数据, 1 ≤ n ≤ 1000 1≤n≤1000。 对于 100 % 100% 的数据, 1 ≤ n ≤ 10 5 1≤n≤10 5 , 0 ≤ x 1 < x 2 ≤ 10 9 0≤x 1 ​ <x 2 ​ ≤10 9 , 0 ≤ y 1 < y 2 ≤ 10 9 0≤y 1 ​ <y 2 ​ ≤10 9 。
我的代码:
CPP
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=2e5+10;
struct Line{
   long long y1,y2,x,mark;
}lineSeg[N];
long long y[N];
long long n,ans;
struct Node{
   int l,r;
   long long cover;
   long long len;
}tree[4*N];
bool cmp(Line a,Line b){
   return a.x<b.x;
}
void build(int p,int l,int r){
   tree[p].l=l;
   tree[p].r=r;
   tree[p].cover=0;
   tree[p].len=0;
   if(l==r)return;
   int mid=(l+r)/2;
   build(p*2,l,mid);
   build(p*2+1,mid+1,r);
}
void pushup(int p){
   if(tree[p].cover>0){
   	tree[p].len=y[tree[p].r+1]-y[tree[p].l];
   }
   else {
   	if(tree[p].l==tree[p].r){
   		tree[p].len=0;
   	}
   	else {
   		tree[p].len=tree[p*2].len+tree[p*2+1].len;
   	}
   }
}
void undate(int p,int l,int r,int val){
   if(l<=tree[p].l&&tree[p].r<=r){
   	tree[p].cover+=val;
   	pushup(p);
   	return;
   }
   int mid=(tree[p].l+tree[p].r)/2;
   if(l<=mid){
   	undate(p*2,l,r,val);
   }
   if(r>mid){
   	undate(p*2+1,l,r,val);
   }
   pushup(p);
}
signed main(){
   ios::sync_with_stdio(false);
   cin.tie(0),cout.tie(0);
   cin>>n;
   long long x1,x2,y1,y2;
   long long sum=0;
   for(int i=1;i<=n;i++){
   	cin>>x1>>y1>>x2>>y2;
   	sum+=abs((x1-x2)*(y1-y2));
   	lineSeg[i*2-1]={y1,y2,x1,1};
   	lineSeg[i*2]={y1,y2,x2,-1};
   	y[i*2-1]=y1;
   	y[i*2]=y2;
   }
   int m=n*2;
   sort(y+1,y+m+1);
   int cnt=unique(y+1,y+m+1)-(y+1);
   sort(lineSeg+1,lineSeg+m+1,cmp);
   build(1,1,cnt-1);
   for(int i=1;i<=m;i++){
   	int L=lower_bound(y+1,y+cnt+1,lineSeg[i].y1)-y;
   	int R=lower_bound(y+1,y+cnt+1,lineSeg[i].y2)-y-1;
   	if(L<=R)undate(1,L,R,lineSeg[i].mark);
   	long long delax=lineSeg[i+1].x-lineSeg[i].x;
   	ans+=tree[1].len*delax;
   }
   cout<<(2*ans-sum)<<"\n";
   return 0;
}
60pts,WA

回复

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

正在加载回复...