CodeVs 3044扫描线

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/yqdjl6/article/details/82016384

这道题其实就是线段树区间覆盖的变形,裸的扫描线问题,其中有一个坑点是点不是整数,我们需要离散化一下,这里离散化的结果是,每个点是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;
}

猜你喜欢

转载自blog.csdn.net/yqdjl6/article/details/82016384