CodeVs 3044扫描线

本文深入解析了线段树区间覆盖算法的实现细节,通过一个具体的编程实例,介绍了如何处理非整数点的问题,使用离散化方法,并详细展示了扫描线算法的代码实现,包括节点结构定义、区间更新、懒惰传播等关键步骤。

这道题其实就是线段树区间覆盖的变形,裸的扫描线问题,其中有一个坑点是点不是整数,我们需要离散化一下,这里离散化的结果是,每个点是i点到i+1点的距离,区间更新的时候尤其要注意

#include<bits/stdc++.h>
using namespace std;
struct Node {
    double x1,x2,y;
    int flag;
}node[1005];
double mp[1005],sum[1005];
int lazy[1005];
bool cmp(Node a,Node b) {return a.y<b.y;}

void push_up(int num,int l,int r) {
    if(lazy[num]) sum[num]=mp[r]-mp[l];
    else if(l==r) sum[num]=0;
    else sum[num]=sum[num<<1]+sum[num<<1|1];
}

void update(int num,int l,int r,int L,int R,int add) {
    if(L<=l&&R>=r) {
        lazy[num]+=add;
        push_up(num,l,r);
        return ;
    }
    int mid=(l+r)/2;
    if(L<=mid) update(num<<1,l,mid,L,R,add);
    if(R>mid) update(num<<1|1,mid+1,r,L,R,add);
    push_up(num,l,r);
}

int main()
{
    ios::sync_with_stdio(0);
    cin.tie(0);
    int n;
    while(cin>>n,n) {
        memset(sum,0,sizeof(sum));
        memset(lazy,0,sizeof(lazy));
        for(int i=1;i<=n;i++) {
            double x1,y1,x2,y2;
            cin>>x1>>y1>>x2>>y2;
            node[2*i-1].x1=node[2*i].x1=x1;
            node[2*i-1].x2=node[2*i].x2=x2;
            node[2*i-1].y=y1;node[2*i].y=y2;
            node[2*i-1].flag=1;node[2*i].flag=-1;
            mp[2*i-1]=x1,mp[2*i]=x2;
        }
        sort(mp+1,mp+1+2*n);
        sort(node+1,node+1+2*n,cmp);
        double ans=0;
        for(int i=1;i<=2*n;i++) {
            int l=lower_bound(mp+1,mp+1+2*n,node[i].x1)-mp;
            int r=lower_bound(mp+1,mp+1+2*n,node[i].x2)-mp;
            if(l<=r) update(1,1,2*n,l,r,node[i].flag);
            ans+=sum[1]*(node[i+1].y-node[i].y);
        }
        cout<<fixed<<setprecision(2)<<ans<<endl;
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值