线段树区间合并+扫描线

线段树区间合并+扫描线

题目:求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("*");
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值