社区讨论
线段树6倍空间
P5490【模板】扫描线 & 矩形面积并参与者 4已保存回复 4
讨论操作
快速查看讨论及其快照的属性,并进行相关操作。
- 当前回复
- 4 条
- 当前快照
- 1 份
- 快照标识符
- @mhj0fozr
- 此快照首次捕获于
- 2025/11/03 18:41 4 个月前
- 此快照最后确认于
- 2025/11/03 18:41 4 个月前
经自测,线段树大概要开到6倍,八倍肯定是可以通过,求解释线段树使用空间
CPP#include<iostream>
#include<algorithm>
using namespace std;
long long pos[200005];
struct Node
{
long long l;
long long r;
long long x;
long long flag;
}line[200005];
struct node
{
long long l;
long long r;
long long cnt;
long long len;
}t[600005];
long long len;
bool cmp(Node a,Node b)
{
if(a.x==b.x) return a.flag<b.flag;
return a.x<b.x;
}
void build(int p,int l,int r)
{
t[p].l=l,t[p].r=r;
if(l==r) return ;
int mid=(l+r)/2;
build(p*2,l,mid);
build(p*2+1,mid+1,r);
return ;
}
void pushup(int p)
{
if(t[p].cnt>0) t[p].len=pos[t[p].r+1]-pos[t[p].l];
else
{
if(t[p].l==t[p].r) t[p].len=0;
else t[p].len=t[p*2].len+t[p*2+1].len;
}
return ;
}
void update(int p,int l,int r,int d)
{
if(t[p].l>=l&&t[p].r<=r)
{
t[p].cnt+=d;
pushup(p);
return;
}
int mid=(t[p].l+t[p].r)/2;
if(l<=mid) update(p*2,l,r,d);
if(r>mid) update(p*2+1,l,r,d);
pushup(p);
return ;
}
int main()
{
int n;
cin>>n;
for(int i=1;i<=n;i++)
{
long long x,y,xx,yy;
cin>>x>>y>>xx>>yy;
if(x>xx) swap(x,xx);
if(y>yy) swap(y,yy);
pos[i*2-1]=y,pos[i*2]=yy;
line[i*2-1]={y,yy,x,1},line[i*2]={y,yy,xx,-1};
}
sort(pos+1,pos+2*n+1);
int cnt=unique(pos+1,pos+2*n+1)-(pos+1);
sort(line+1,line+2*n+1,cmp);
build(1,1,cnt-1);
long long ans=0;
for(int i=1;i<2*n;i++)
{
int l=lower_bound(pos+1,pos+cnt+1,line[i].l)-pos;
int r=lower_bound(pos+1,pos+cnt+1,line[i].r)-pos;
if(l<r) update(1,l,r-1,line[i].flag);
ans+=t[1].len*(line[i+1].x-line[i].x);
}
cout<<ans;
return 0;
}
回复
共 4 条回复,欢迎继续交流。
正在加载回复...