软件工程今日总结
三个小时
300
include<bits/stdc++.h>
using namespace std;
define int long long
int n,x,y,xx,yy;
const int maxn=100010;
struct scan//记录矩形上下边的位置
{
int l,r,h,tag;
}lines[maxn<<1];
bool cmp(scan s,scan ss)//根据线的高度排序
{
if(s.h!=ss.h)
{
return s.h<ss.h;
}
return s.tag>ss.tag;
}
int ans;
int xcnt,xaxis[maxn<<1];
map<int,int> mp;
//以下为线段树
struct point
{
int l,r,minn,minlen,add;
}tree[maxn<<3];
inline void pushup(int x)
{
int lson=x<<1,rson=lson|1;
tree[x].minn=min(tree[lson].minn,tree[rson].minn);
tree[x].minlen=0;
if(tree[x].minntree[lson].minn)tree[x].minlen+=tree[lson].minlen;
if(tree[x].minntree[rson].minn)tree[x].minlen+=tree[rson].minlen;
}
inline void pushadd(int x,int k)
{
tree[x].add+=k;
tree[x].minn+=k;
}
inline void pushdown(int x)
{
if(tree[x].ltree[x].r)return;
int lson=x<<1,rson=lson|1;
if(tree[x].add!=0)
{
pushadd(lson,tree[x].add);
pushadd(rson,tree[x].add);
tree[x].add=0;
}
}
void build(int x,int l,int r)
{
tree[x]=(point){l,r,0,0,0};
if(lr)
{
tree[x].minlen=xaxis[tree[x].r+1]-xaxis[tree[x].l];
return;
}
int mid=(tree[x].l+tree[x].r)>>1,lson=x<<1,rson=lson|1;
build(lson,l,mid);build(rson,mid+1,r);
pushup(x);
}
void modify(int x,int l,int r,int k)
{
pushdown(x);
if(l<=tree[x].l&&r>=tree[x].r){pushadd(x,k);return;}
int mid=(tree[x].l+tree[x].r)>>1,lson=x<<1,rson=lson|1;
if(l<=mid)modify(lson,l,r,k);
if(r>mid)modify(rson,l,r,k);
pushup(x);
}
inline int getlen()
{
if(tree[1].minn>0)return xaxis[tree[1].r+1]-xaxis[tree[1].l];
else return xaxis[tree[1].r+1]-xaxis[tree[1].l]-tree[1].minlen;
}
//以上为线段树
signed main()
{
cin>>n;
for(int i=1;i<=n;i++)
{
cin>>x>>y>>xx>>yy;
lines[2i-1]=(scan){x,xx,y,1};//储存线的信息
lines[2i]=(scan){x,xx,yy,-1};
xaxis[2i-1]=x;xaxis[2i]=xx;
}
sort(xaxis+1,xaxis+2n+1);
xcnt=unique(xaxis+1,xaxis+2n+1)-xaxis-1;
for(int i=1;i<=xcnt;i++)mp[xaxis[i]]=i;//离散化
sort(lines+1,lines+2n+1,cmp);
build(1,1,xcnt-1);
for(int i=1;i<=2n;i++)
{
ans+=getlen()*(lines[i].h-lines[i-1].h);
modify(1,mp[lines[i].l],mp[lines[i].r]-1,lines[i].tag);//记录答案
}
printf("%lld\n",ans);
return 0;
}
该代码是通过扫描线来解决面积重复的问题

浙公网安备 33010602011771号