P5490 【模板】扫描线

题目链接

题面:
在这里插入图片描述

代码:

#include<iostream>
#include<cstdlib>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<string>
#include<cmath>
#include<queue>
#include<map>
#include<vector>
#define ll long long
#define llu unsigned ll
#define int ll
using namespace std;
const int maxn=201000;
int x[maxn<<1];
struct node
{
    int x1,x2,y;
    int now;
    node(int a=0,int b=0,int c=0,int d=0)
    {
        x1=a,x2=b,y=c,now=d;
    }
    bool operator <(const node &b)const
    {
        return y<b.y;
    }
}a[maxn<<1];

struct Tree
{
    int l,r;
    int sum,laz;
}t[maxn<<3];

void init(int p)
{
    t[p].sum=t[p].laz=0;
}

void build(int l,int r,int cnt)
{
    t[cnt].l=l,t[cnt].r=r;
    init(cnt);
    if(l==r)
    {
        init(cnt<<1);
        init(cnt<<1|1);
        return ;
    }
    int mid=(l+r)>>1;
    build(l,mid,cnt<<1);
    build(mid+1,r,cnt<<1|1);
}

void pushup(int p)
{
    if(t[p].laz) t[p].sum=x[t[p].r+1]-x[t[p].l];
    else t[p].sum=t[p<<1].sum+t[p<<1|1].sum;
}

void change(int l,int r,int val,int cnt)
{
    if(l<=t[cnt].l&&t[cnt].r<=r)
    {
        t[cnt].laz+=val;
        pushup(cnt);
        return ;
    }
    if(l<=t[cnt<<1].r) change(l,r,val,cnt<<1);
    if(r>=t[cnt<<1|1].l) change(l,r,val,cnt<<1|1);
    pushup(cnt);
}

signed main(void)
{
    int n,x1,y1,x2,y2;
    int cnt=0;
    scanf("%lld",&n);
    for(int i=1;i<=n;i++)
    {
        scanf("%lld%lld%lld%lld",&x1,&y1,&x2,&y2);
        x[++cnt]=x1,a[cnt]=node(x1,x2,y1,1);
        x[++cnt]=x2,a[cnt]=node(x1,x2,y2,-1);
    }
    sort(x+1,x+cnt+1);
    sort(a+1,a+cnt+1);
    int tot=unique(x+1,x+cnt+1)-(x+1);
    build(1,tot,1);
    int ans=0;
    for(int i=1;i<=cnt;i++)
    {
        ans=ans+t[1].sum*(a[i].y-a[i-1].y);
        change(lower_bound(x+1,x+tot+1,a[i].x1)-x,lower_bound(x+1,x+tot+1,a[i].x2)-x-1,a[i].now,1);
    }
    printf("%lld\n",ans);
    return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值