题意:

给n个矩形坐标,可能重合,求整体周长

思路:

扫描线扫两遍,从左到右扫一遍,从上到下扫一遍,但是和扫面积略有不同,我们的tr[1].sum的值需要和上一条边进行比较,然后再添加到ans中,我们利用线段树求出tr[1].sum便是当前扫到的整体长度,累加求和即可

注意:
1:这题多组输入,一开始没注意,wa了两发
2:注意清空线段树中的标记和区间长度,遍历一下节点即可清空

参考代码:

#include<bits/stdc++.h>
using namespace std;
typedef unsigned long long ull;
typedef long long ll;
#define inf 1<<28
const ll base=13331;
const ll maxn=1e5+5;
#define lson k<<1
#define rson k<<1|1
#define mid ((l+r)>>1)
using namespace std;
struct line
{
ll x,y,h,lazy;
} p[maxn<<1];
struct node
{
ll sum,num,len;
bool lflag,rflag;
} tr[maxn<<3];
ll n,mx=-inf,mn=inf,cnt,ans,las;
void add(ll l,ll r,ll h,ll f)
{
p[++cnt].x=l;
p[cnt].y=r;
p[cnt].h=h;
p[cnt].lazy=f;
}
bool cmp(line a,line b)
{
return a.h<b.h||a.h==b.h&&a.lazy>b.lazy;
}
void pushup(ll k,ll l,ll r)
{
if(tr[k].sum)
{
tr[k].num=1;
tr[k].len=r-l+1;
tr[k].lflag=tr[k].rflag=1;
}
else if(l==r)
{
tr[k].len=0;
tr[k].num=0;
tr[k].lflag=tr[k].rflag=0;
}
else
{
tr[k].len=tr[lson].len+tr[rson].len;
tr[k].num=tr[lson].num+tr[rson].num;
if(tr[lson].rflag&&tr[rson].lflag)tr[k].num--;
tr[k].lflag=tr[lson].lflag;
tr[k].rflag=tr[rson].rflag;
}
}
void build(int k,int l,int r)
{
tr[k].lflag=tr[k].rflag=false;
tr[k].sum=0;
if(l==r)
return;
build(lson,l,mid);
build(rson,mid+1,r);
}
void modify(ll k,ll l,ll r,ll L,ll R,ll value)
{
if(l>=L&&r<=R)
{
tr[k].sum+=value;
pushup(k,l,r);
return;
}
if(L<=mid)modify(lson,l,mid,L,R,value);
if(R>mid)modify(rson,mid+1,r,L,R,value);
pushup(k,l,r);
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
while(cin>>n&&n)
{
mx=-inf,mn=inf,cnt=0,ans=0,las=0;
build(1,1,n);
for(ll i=1; i<=n; i++)
{
ll x1,y1,x2,y2;
cin>>x1>>y1>>x2>>y2;
mx=max(mx,max(x1,x2));
mn=min(mn,min(x1,x2));
add(x1,x2,y1,1);
add(x1,x2,y2,-1);
}
if(mn<=0)
{
for(ll i=1; i<=cnt; i++)
{
p[i].x+=-mn+1;
p[i].y+=-mn+1;
}
mx-=mn;
}
sort(p+1,p+cnt+1,cmp);
for(ll i=1; i<=cnt; i++)
{
modify(1,1,mx,p[i].x,p[i].y-1,p[i].lazy);
while(p[i].h==p[i+1].h&&p[i].lazy==p[i+1].lazy)
{
i++;
modify(1,1,mx,p[i].x,p[i].y-1,p[i].lazy);
}
ans+=abs(tr[1].len-las);
las=tr[1].len;
ans+=tr[1].num*2*(p[i+1].h-p[i].h);
}
cout<<ans<<endl;
}
}