清北学堂-D5-T2-bw

本文介绍了一种利用线段树解决区间更新问题的方法。通过将复杂区域划分成多个线段进行排序和特殊处理,实现了区域面积的有效计算。文中提供了一份未通过全部测试案例的示例代码。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

这里写图片描述
这个题可以发现整个面积可以被拆成许多条线段的询问,然后排个序,特判一下,判出来是加还是减,然后算就好了。
代码:(没有AC,错误代码)

#include<cstdio>
#include<cstring>
#include<iostream>
#include<cmath>
#include<algorithm>
#include<cstdlib>
#include<queue>
#define ll long long
using namespace std;
inline int read(){
    int x=0;char ch=' ';int f=1;
    while(ch!='-'&&(ch<'0'||ch>'9'))ch=getchar();
    if(ch=='-')f=-1,ch=getchar();
    while(ch>='0'&&ch<='9')x=x*10+ch-'0',ch=getchar();
    return x*f;
}
const int inf=2000000000;
int n;
struct line{
    ll x,y1,y2;
    int t;
    line(){}
    line(int xx,int yy1,int yy2){
        if(yy1>yy2)swap(yy1,yy2);
        this->x=xx;
        this->y1=yy1;
        this->y2=yy2;
    }
    inline bool operator > (const line& b) const {
        return y2>b.y2;
    }
}a[50001];
int x[50001],y[50001];
bool cmp1(line& x,line& y){
    return x.x>y.x;
}
bool cmp2(line& x,line& y){
    return x.y1==y.y1?x.x>y.x:x.y1<y.y1;
}
ll bd=-inf;
priority_queue<line,vector<line>,greater<line> > q;
int main(){
    freopen("bw.in","r",stdin);
    freopen("bw.out","w",stdout);
    n=read();
    int mn=inf;
    int mx=-inf;
    for(int i=1;i<=n;i++){
        x[i]=read();
        y[i]=read();
        mn=min(mn,y[i]);
        mx=max(mx,y[i]);
    }
    a[1]=line(x[1],y[1],y[n]);
    for(int i=2;i<=n;i+=2){
        a[i/2+1]=line(x[i],y[i],y[i+1]);
    }
    sort(a+1,a+n/2+1,cmp2);
    for(int i=1;i<=n/2;i++){
        while(!q.empty()&&q.top().y2<=a[i].y1){
            q.pop();
        }
        int opt=q.size()/2;
        if(i&1){
            if(opt&1){
                a[i].t=-1;
            }
            else{
                a[i].t=1;
            }
        }
        else{
            if(opt&1){
                a[i].t=1;
            }
            else{
                a[i].t=-1;
            }
        }
        q.push(a[i]);
    }
    sort(a+1,a+n/2+1,cmp1);
    ll bai=0;
    ll hei=0;
    for(int i=1;i<=n/2;i++){
        if((a[i].x+a[i].y1)&1){
            //hei
            bool c1=(a[i].y2-a[i].y1)&1;
            bool c2=(a[i].x-bd)&1;
            ll num=(a[i].y2-a[i].y1)*(a[i].x-bd);
            if(c1&&c2){
                hei+=a[i].t*(num/2+1);
                bai+=a[i].t*(num/2);
            }
            else{
                hei+=a[i].t*(num/2);
                bai+=a[i].t*(num/2);
            }
        }
        else{
            //bai
            bool c1=(a[i].y2-a[i].y1)&1;
            bool c2=(a[i].x-bd)&1;
            ll num=(a[i].y2-a[i].y1)*(a[i].x-bd);
            if(c1&&c2){
                hei+=a[i].t*(num/2);
                bai+=a[i].t*(num/2+1);
            }
            else{
                hei+=a[i].t*(num/2);
                bai+=a[i].t*(num/2);
            }
        }
    }
    printf("%I64d %I64d",hei,bai);
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值