社区讨论
求助模拟赛题
学术版参与者 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 条回复,欢迎继续交流。
正在加载回复...