关于扫描线的介绍可以去看 OI Wiki

但那上面的参考代码并不好,下面给出了带注释的 POJ 1389 题代码。

/*
 * Title: Area of Simple Polygons
 * Source: POJ
 * URL: http://poj.org/problem?id=1389
 * Author: Steven_lzx
 * Command: -std=c++23 -Wall -fno-ms-extensions
 * Date: 2022.10.19
 */
#include <cstdio>
#include <algorithm>
using namespace std;
typedef long long ll;
const int MAXN=2005,MAXM=200005;
struct Rec
{
    int x1,x2,y,w;
    bool operator <(Rec b)const{return y<b.y;}
}p[2005];
int tree[MAXM],lazy[MAXM];
void build(int p,int l,int r)
{
    int mid;
    lazy[p]=0;
    if(l==r)
    {
        tree[p]=0;
        return;
    }
    mid=(l+r)>>1;
    build(p<<1,l,mid);
    build(p<<1|1,mid+1,r);
    tree[p]=tree[p<<1]+tree[p<<1|1];
    return;
}
void update(int p,int l,int r,const int L,const int R,int c)
{
    int mid;
    if(R<l||L>r)
        return;
    if(L<=l&&r<=R)
    {
        lazy[p]+=c;
        if(lazy[p]>0)
            tree[p]=r-l+1;//完全覆盖,值为区间长
        else if(l==r)
            tree[p]=0;//该点没有被覆盖,清零
        else 
            tree[p]=tree[p<<1]+tree[p<<1|1];//没有被完全覆盖,需要重新更新 
        return;
    }
    mid=(l+r)>>1;
    update(p<<1,l,mid,L,R,c);
    update(p<<1|1,mid+1,r,L,R,c);
    if(!lazy[p])
        tree[p]=tree[p<<1]+tree[p<<1|1];//没有被完全覆盖,需要重新更新
    return;
}
int main()
{
    int n,a,b,c,d;
    ll h,ans;
    bool over=false;
    while(true)
    {
        n=0;
        while(true)
        {
            scanf("%d%d%d%d",&a,&b,&c,&d);
            if(!~a&&!~b&&!~c&&!~d)
            {
                if(!n)
                    over=true;
                break;
            }
            n++;
            p[n*2].x1=p[n*2-1].x1=a;
            p[n*2-1].y=b;
            p[n*2].x2=p[n*2-1].x2=c;
            p[n*2].y=d;
            p[n*2-1].w=1;
            p[n*2].w=-1;
        }
        if(over)
            break;
        sort(p+1,p+(n<<1)+1);
        build(1,0,5e4);
        ans=0;
        update(1,0,5e4,p[1].x1+1,p[1].x2,p[1].w);//建一个底
        for(int i=2;i<=n<<1;i++)//因为是点数和,所有求长度的话要减去一个点就为长度
        {
            h=p[i].y-p[i-1].y;
            ans+=h*tree[1];//底乘高
            update(1,0,5e4,p[i].x1+1,p[i].x2,p[i].w);
        }
        printf("%lld\n",ans);
    }
    return 0;
}

原文地址:http://www.cnblogs.com/2020gyk080/p/16806259.html

1. 本站所有资源来源于用户上传和网络,如有侵权请邮件联系站长! 2. 分享目的仅供大家学习和交流,请务用于商业用途! 3. 如果你也有好源码或者教程,可以到用户中心发布,分享有积分奖励和额外收入! 4. 本站提供的源码、模板、插件等等其他资源,都不包含技术服务请大家谅解! 5. 如有链接无法下载、失效或广告,请联系管理员处理! 6. 本站资源售价只是赞助,收取费用仅维持本站的日常运营所需! 7. 如遇到加密压缩包,默认解压密码为"gltf",如遇到无法解压的请联系管理员! 8. 因为资源和程序源码均为可复制品,所以不支持任何理由的退款兑现,请斟酌后支付下载 声明:如果标题没有注明"已测试"或者"测试可用"等字样的资源源码均未经过站长测试.特别注意没有标注的源码不保证任何可用性