hihocoder1305(打标记)

本文介绍了一种算法,用于解决两个区间集合的差集问题,并通过具体示例解释了如何计算两个区间集合A和B的差集A-B的长度。

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

链接:点击打开链接

题意:给定两个区间集合 A 和 B,其中集合 A 包含 N 个区间[ A1, A2 ], [ A3, A4 ], ..., [ A2N-1, A2N ],集合 B 包含 M 个区间[ B1, B2 ], [ B3, B4 ], ..., [ B2M-1, B2M ]。求 A - B 的长度。
例如对于 A = {[2, 5], [4, 10], [14, 18]}, B = {[1, 3], [8, 15]}, A - B = {(3, 8), (15, 18]},长度为8。

代码:

#include <queue>
#include <vector>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <iostream>
#include <algorithm>
using namespace std;
struct node{
    int id,le,x;
    friend bool operator<(node a,node b){
        return a.x<b.x;
    }
}s[500005];
int main(){                                     //直接将所有点进行排序,进行打标记
    int n,m,i,j,u,ans,sum1,sum2;                //区分是哪一种点的左端还是右端,用
    while(scanf("%d%d",&n,&m)!=EOF){            //两个值分别维护两种点的值
        u=0;
        for(i=1;i<=n;i++){
            scanf("%d",&s[u].x);
            s[u].id=1,s[u].le=1;
            u++;
            scanf("%d",&s[u].x);
            s[u].id=1,s[u].le=2;
            u++;
        }
        for(i=1;i<=m;i++){
            scanf("%d",&s[u].x);
            s[u].id=2,s[u].le=1;
            u++;
            scanf("%d",&s[u].x);
            s[u].id=2,s[u].le=2;
            u++;
        }                                       //标记是左端还是右端
        sort(s,s+u);
        ans=sum1=sum2=0;
        for(i=0;i<=u-1;i++){
            if(s[i].id==1){                     //遇到第一种点的左端点就加一,右端点就减一
                if(s[i].le==1)                  //第二种点也是一样,当区间中sum1>0&&sum2<0
                sum1++;                         //时就是A-B的一部分
                else                            //详细题解可以看hiho一下第152周的讨论,里面
                sum1--;                         //有很详细的讲解
            }
            else{
                if(s[i].le==1)
                sum2++;
                else
                sum2--;
            }
            if(sum1>0&&sum2==0)
            ans+=(s[i+1].x-s[i].x);
        }
        printf("%d\n",ans);
    }
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值