线段树区间合并+扫描线
题目:求N个矩形面积并
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e6+5;
int t[N*2]; //标记数量
int vis[N+2]; //标记数组
void update(int root,int kl,int kr,int num,int l=1,int r=N){
if(l==r){ //线段树传入参数:当前根地址,操作区间,更改值,当前递归区间
vis[l]+=num; //vis的作用是记录多少个矩形覆盖了这个区间,但无论加了多少num,对t[]来说这区间计算面积只有计1与不计0
if(vis[l]==0)t[root]=0;
else t[root]=1;
return;
}
int mid=(l+r)/2;
if(kl<=mid)update(root*2,kl,kr,num,l,mid);
if(kr>mid)update(root*2+1,kl,kr,num,mid+1,r);
t[root]=t[root*2]+t[root*2+1];
}//值为其两个儿子之和
struct node{//存边
int l,r,y,flag; //横边,高度,朝向
}p[2200];
bool cmp(node a,node b){
return a.y<b.y;
}
int main(){
int n,a,b,c,d;
while(scanf("%d",&n),n){
for(int i=1;i<=n;i++){
scanf("%d%d%d%d",&a,&b,&c,&d);
p[i]=node{a,c,b,1};//下边
p[i+n]=node{a,c,d,-1};//上边
}
sort(p+1,p+2*n+1,cmp); //把边从下到上排序
memset(vis,0,sizeof(vis));
ll ans=0; //总面积初始化
for(int i=1;i<=2*n;i++){
ans+=(ll)(p[i].y-p[i-1].y)*t[1]; //当前累积的面积
update(1,p[i].l+1,p[i].r,p[i].flag);
}//根1,当前边左值,右值,标记
printf("%lld\n",ans);
}
puts("*");
}