[洛谷2434] [SDOI2005]区间 线段树

本文介绍了一种利用线段树解决寻找最小数量不相交闭区间问题的方法。通过对给定的多个闭区间进行特定转换和遍历,有效地找到满足条件的区间集合,并按升序输出。

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

题目描述

现给定n个闭区间[ai, bi],1<=i<=n。这些区间的并可以表示为一些不相交的闭区间的并。你的任务就是在这些表示方式中找出包含最少区间的方案。你的输出应该按照区间的升序排列。这里如果说两个区间[a, b]和[c, d]是按照升序排列的,那么我们有a<=b<c<=d。

请写一个程序:

读入这些区间;

计算满足给定条件的不相交闭区间;

把这些区间按照升序输出。

输入输出格式

输入格式:

第一行包含一个整数n,3<=n<=50000,为区间的数目。以下n行为对区间的描述,第i行为对第i个区间的描述,为两个整数1<=ai<bi<=1000000,表示一个区间[ai, bi]。

输出格式:

输出计算出来的不相交的区间。每一行都是对一个区间的描述,包括两个用空格分开的整数,为区间的上下界。你应该把区间按照升序排序。


题解:

其实这题有很多简单的方法可以解决,但我们为了练习线段树的能力,用线段树来实现它。我们把区间[u,v]变成[u*2,v*2],并每次对这个区间整体+1,这样可以保证两个区间的边界处不会被增加。然后枚举出现过的数,一个个统计答案即可。

AC代码:

#include<cstdio>
#include<iostream>
#define ll int
using namespace std;
const int Maxn=2000015;
ll a[Maxn];
struct node{
    ll x,c;
    int l,r; 
}t[Maxn*8]; 
int m;
inline int lson(int x){
    return x*2;
}
inline int rson(int x){
    return x*2+1;
}
inline int pushup(int rt){
    t[rt].x=t[lson(rt)].x+t[rson(rt)].x;
}
inline void build(int l,int r,int rt){
    t[rt].l=l;t[rt].r=r;
    if(l==r){
        t[rt].x=a[l];
        return;
    }
    int mid=l+r>>1;
    build(l,mid,lson(rt));
    build(mid+1,r,rson(rt));
    pushup(rt);
}
inline int len(int rt){
    return t[rt].r-t[rt].l+1;
}
inline void pushdown(int rt){
    if(t[rt].l==t[rt].r)return;
    if(t[rt].c==0)return;
    t[lson(rt)].c+=t[rt].c;
    t[rson(rt)].c+=t[rt].c;
    t[lson(rt)].x+=t[rt].c*len(lson(rt));
    t[rson(rt)].x+=t[rt].c*len(rson(rt));
    t[rt].c=0;
}
inline void update(int l,int r,ll x,int rt){
    if(t[rt].l>=l&&t[rt].r<=r){
        t[rt].x+=x*len(rt);
        t[rt].c+=x;
        return;
    }
    pushdown(rt);
    int mid=t[rt].l+t[rt].r>>1;
    if(l<=mid){
        update(l,r,x,lson(rt));
    }
    if(r>mid){
        update(l,r,x,rson(rt));
    }
    pushup(rt);
}
inline ll query(int l,int rt){
    if(t[rt].l==l&&t[rt].r==l){
        return t[rt].x;
    }
    pushdown(rt);
    int mid=t[rt].l+t[rt].r>>1;
    if(l<=mid)return query(l,lson(rt));
    else return query(l,rson(rt));
}
inline int mx(int x,int y){
    return x>y?x:y;
}
int main(){
    int u,v,inc,maxn,now=1;
    bool flag=1;
    scanf("%d",&m);
    build(1,2000005,1);
    while(m--){
        scanf("%d%d",&u,&v);
        update(u*2,v*2,1,1);
        maxn=mx(maxn,v*2);
    }
    while(now<=maxn){
        if(flag==0){
            printf("%d ",now/2);
            while(query(now,1)&&now<=maxn)now++;
            printf("%d\n",now/2);
            flag=1;
        }
        else{
            while(!query(now,1)&&now<=maxn)now++;
            flag=0;
        }
    }
    return 0;
}

电动汽车数据集:2025年3K+记录 真实电动汽车数据:特斯拉、宝马、日产车型,含2025年电池规格和销售数据 关于数据集 电动汽车数据集 这个合成数据集包含许多品牌和年份的电动汽车和插电式车型的记录,捕捉技术规格、性能、定价、制造来源、销售和安全相关属性。每一行代表由vehicle_ID标识的唯一车辆列表。 关键特性 覆盖范围:全球制造商和车型组合,包括纯电动汽车和插电式混合动力汽车。 范围:电池化学成分、容量、续航里程、充电标准和速度、价格、产地、自主水平、排放、安全等级、销售和保修。 时间跨度:模型跨度多年(包括传统和即将推出的)。 数据质量说明: 某些行可能缺少某些字段(空白)。 几个分类字段包含不同的、特定于供应商的值(例如,Charging_Type、Battery_Type)。 各列中的单位混合在一起;注意kWh、km、hr、USD、g/km和额定值。 列 列类型描述示例 Vehicle_ID整数每个车辆记录的唯一标识符。1 制造商分类汽车品牌或OEM。特斯拉 型号类别特定型号名称/变体。型号Y 与记录关联的年份整数模型。2024 电池_类型分类使用的电池化学/技术。磷酸铁锂 Battery_Capacity_kWh浮充电池标称容量,单位为千瓦时。75.0 Range_km整数表示充满电后的行驶里程(公里)。505 充电类型主要充电接口或功能。CCS、NACS、CHAdeMO、DCFC、V2G、V2H、V2L Charge_Time_hr浮动充电的大致时间(小时),上下文因充电方法而异。7.5 价格_USD浮动参考车辆价格(美元).85000.00 颜色类别主要外观颜色或饰面。午夜黑 制造国_制造类别车辆制造/组装的国家。美国 Autonomous_Level浮点自动化能力级别(例如0-5),可能包括子级别的小
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值