【kuangbin带我飞】专题七 线段树

本文提供了线段树的基本模板,包括建树、点修改、区间修改及查询的实现方法。适用于处理区间操作问题,如求区间和、最大值等。

由于我不会线段树,先弄一份模板。

基本线段树模板(建树、点/区间修改、查询)

基础线段树(闭区间)(单点修改、单点查询):

const int MAXM=50000;          //定义 MAXM 为线段最大长度

int a[MAXM+5],st[(MAXM<<2)+5];    // a 数组为 main 函数中读入的内容,st 数组为需要查询的数的信息(如和、最值等),树的空间大小为线段最大长度的四倍

//建树
void build(int o,int l,int r){    //传入的参数为 o:当前需要建立的结点;l:当前需要建立的左端点;r:当前需要建立的右端点
    if(l==r)st[o]=a[l];      //当左端点等于右端点即建立叶子结点时,直接给数组信息赋值
    else{
        int m=l+((r-l)>>1);      // m 为中间点,左儿子结点为 [l,m] ,右儿子结点为 [m+1,r];
        build(o<<1,l,m);        //构建左儿子结点
        build((o<<1)|1,m+1,r);     //构建右儿子结点
        st[o]=st[o<<1]+st[(o<<1)|1];  //递归返回时用儿子结点更新父节点,此处可进行更新最大值、最小值、区间和等操作
    }
}

//在 main 函数中的语句 build(1,1,n);

//单点修改
void update(int o,int l,int r,int ind,int ans){  //o、l、r为当前更新到的结点、左右端点,ind为需要修改的叶子结点左端点,ans为需要修改成的值;
    if(l==r){                      //若当前更新点的左右端点相等即到叶子结点时,直接更新信息并返回
        st[o]=ans;
        return;
    }
    int m=l+((r-l)>>1);
    if(ind<=m){                      //若需要更新的叶子结点在当前结点的左儿子结点的范围内,则递归更新左儿子结点,否则更新右儿子结点
        update(o<<1,l,m,ind,ans);
    }
    else{
        update((o<<1)|1,m+1,r,ind,ans);
    }
    st[o]=max(st[o<<1],st[(o<<1)|1]);//递归回之后用儿子结点更新父节点(此处是区间最大值)
}

//在main函数中的语句 update(1,1,n,ind,ans);

//对应单点修改的单点查询
int query(int o,int l,int r,int ql,int qr){      //ql、qr为需要查询的区间左右端点
    if(ql>r||qr<l) return -1;              //若当前结点和需要查找的区间不相交,则返回一个对于区间查询无关的值(如求和时返回0,求最大值时返回-1等)
    if(ql<=l&&qr>=r) return st[o];        //若当前结点的区间被需要查询的区间覆盖,则返回当前结点的信息
    int m=l+((r-l)>>1);
    int p1=query(o<<1,l,m,ql,qr),p2=query((o<<1)|1,m+1,r,ql,qr);  //p1为查询左儿子结点得到的信息,p2为查询右儿子结点得到的信息
    return max(p1,p2);    //综合两个儿子结点的信息并返回
}

//main函数中的语句 printf("%d\n",query(1,1,n,a,b));

整理压行版基础线段树(闭区间):

const int MAXM=50000;                     //MAXM 为线段最大长度
int a[MAXM+5],st[(MAXM<<2)+5];        //a数组为原数组,st数组为四倍大小线段树

//求和
int op_init=0;
inline int op_cal(int o1,int o2){
    return o1+o2;
};

void build(int o,int l,int r) {               //o当前结点,l左端点,r右端点,build(1,1,n)                                      
    if(l==r) st[o]=a[l];         
    else {
        int m=l+((r-l)>>1);
        build(o<<1,l,m);
        build((o<<1)|1,m+1,r);
        st[o]=op_cal(st[o<<1],st[(o<<1)|1]);    //子结点建立完成后,更新父节点
    }
}

//单点修改
void update(int o,int l,int r,int ind,int ans){  //ind为叶结点,ans为值,update(1,1,n,ind,ans);
    if(l==r){
        st[o]=ans;
    }
    else{
        int m=l+((r-l)>>1);
        if(ind<=m) update(o<<1,l,m,ind,ans);
        else update((o<<1)|1,m+1,r,ind,ans);
        st[o]=max(st[o<<1],st[(o<<1)|1]);          //子节点更新后,更新父节点
    }
}

//对应单点修改的单点查询
int query(int o,int l,int r,int ql,int qr){     //ql、qr为查询区间左右端点,query(1,1,n,a,b)
    if(ql>r||qr<l) return op_init;              //区间不相交,返回无关值
    if(ql<=l&&qr>=r) return st[o];               //若当前区间被查询区间覆盖,返回当前信息
    int m=l+((r-l)>>1);
    int p1=query(o<<1,l,m,ql,qr);                  //查询左右子结点信息
    int p2=query((o<<1)|1,m+1,r,ql,qr);          
    return op_cal(p1,p2);                      //综合子结点的信息返回
}

A 敌兵布阵

//https://vjudge.net/contest/66989#problem/A
#include<bits/stdc++.h>
using namespace std;
#define ll long long

const int MAXM=50000;                                   //MAXM 为线段最大长度
int a[MAXM+5],st[(MAXM<<2)+5];                          //a数组为原数组st数组为四倍大小线段树

struct SegmentTree{
    int n;  //线段树的大小

    //求和
    int op_init=0;
    inline int op_cal(int o1,int o2){
        return o1+o2;
    };

    void _build(int o,int l,int r) {                     //o当前结点,l左端点,r右端点,_build(1,1,n)
        if(l==r) {st[o]=a[l];return;}
        int m=l+((r-l)>>1);
        _build(o<<1,l,m);
        _build((o<<1)|1,m+1,r);
        st[o]=op_cal(st[o<<1],st[(o<<1)|1]);            //子结点建立完成后,更新父节点
    }

    //单点修改
    void _update(int o,int l,int r,int ind,int ans){     //ind为叶结点,ans为值,_update(1,1,n,ind,ans);
        if(l==r) {st[o]=ans;return;}
        int m=l+((r-l)>>1);
        if(ind<=m) _update(o<<1,l,m,ind,ans);
        else _update((o<<1)|1,m+1,r,ind,ans);
        st[o]=op_cal(st[o<<1],st[(o<<1)|1]);           //子节点更新后,更新父节点
    }

    //对应单点修改的单点查询
    int _query(int o,int l,int r,int ql,int qr){         //ql、qr为查询区间左右端点,_query(1,1,n,a,b)
        if(ql>r||qr<l) return op_init;                  //区间不相交,返回无关值
        if(ql<=l&&qr>=r) return st[o];                  //若当前区间被查询区间覆盖,返回当前信息
        int m=l+((r-l)>>1);                             //综合子结点的信息返回
        return op_cal(_query(o<<1,l,m,ql,qr),_query((o<<1)|1,m+1,r,ql,qr));
    }

    void build(int tn){
        n=tn;
        _build(1,1,n);
    }

    void update(int ind,int ans){
        _update(1,1,n,ind,ans);
    }

    int query(int l,int r){
        return _query(1,1,n,l,r);
    }
};

int main(){
    int T;
    while(~scanf("%d",&T)){
        for(int t=1;t<=T;t++){
            printf("Case %d:\n",t);
            int n;
            scanf("%d",&n);
            for(int i=1;i<=n;i++){
                scanf("%d",&a[i]);
            }
            SegmentTree st;
            st.build(n);
            char ins[10];
            while(1){
                scanf("%s",ins);
                if(ins[0]=='E')
                    break;
                int i,j;
                scanf("%d%d",&i,&j);
                if(ins[0]=='A'){
                    a[i]+=j;
                    st.update(i,a[i]);
                }
                else if(ins[0]=='S'){
                    a[i]-=j;
                    st.update(i,a[i]);
                }
                else if(ins[0]=='Q'){
                    printf("%d\n",st.query(i,j));
                }
            }
        }
    }
}

 

下载前可以先看下教程 https://pan.quark.cn/s/a426667488ae 标题“仿淘宝jquery图片左右切换数字”揭示了这是一个关于运用jQuery技术完成的图片轮播机制,其特色在于具备淘宝在线平台普遍存在的图片切换表现,并且在整个切换环节中会展示当前图片的序列号。 此类功能一般应用于电子商务平台的产品呈现环节,使用户可以便捷地查看多张商品的照片。 说明中的“NULL”表示未提供进一步的信息,但我们可以借助标题来揣摩若干核心的技术要点。 在构建此类功能时,开发者通常会借助以下技术手段:1. **jQuery库**:jQuery是一个应用广泛的JavaScript框架,它简化了HTML文档的遍历、事件管理、动画效果以及Ajax通信。 在此项目中,jQuery将负责处理用户的点击动作(实现左右切换),并且制造流畅的过渡效果。 2. **图片轮播扩展工具**:开发者或许会采用现成的jQuery扩展,例如Slick、Bootstrap Carousel或个性化的轮播函数,以达成图片切换的功能。 这些扩展能够辅助迅速构建功能完善的轮播模块。 3. **即时数字呈现**:展示当前图片的序列号,这需要通过JavaScript或jQuery来追踪并调整。 每当图片切换时,相应的数字也会同步更新。 4. **CSS美化**:为了达成淘宝图片切换的视觉效果,可能需要设计特定的CSS样式,涵盖图片的排列方式、过渡效果、点状指示器等。 CSS3的动画和过渡特性(如`transition`和`animation`)在此过程中扮演关键角色。 5. **事件监测**:运用jQuery的`.on()`方法来监测用户的操作,比如点击左右控制按钮或自动按时间间隔切换。 根据用户的交互,触发相应的函数来执行...
垃圾实例分割数据集 一、基础信息 • 数据集名称:垃圾实例分割数据集 • 图片数量: 训练集:7,000张图片 验证集:426张图片 测试集:644张图片 • 训练集:7,000张图片 • 验证集:426张图片 • 测试集:644张图片 • 分类类别: 垃圾(Sampah) • 垃圾(Sampah) • 标注格式:YOLO格式,包含实例分割的多边形点坐标,适用于实例分割任务。 • 数据格式:图片文件 二、适用场景 • 智能垃圾检测系统开发:数据集支持实例分割任务,帮助构建能够自动识别和分割图像中垃圾区域的AI模型,适用于智能清洁机器人、自动垃圾桶等应用。 • 环境监控与管理:集成到监控系统中,用于实时检测公共区域的垃圾堆积,辅助环境清洁和治理决策。 • 计算机视觉研究:支持实例分割算法的研究和优化,特别是在垃圾识别领域,促进AI在环保方面的创新。 • 教育与实践:可用于高校或培训机构的AI课程,作为实例分割技术的实践数据集,帮助学生理解计算机视觉应用。 三、数据集优势 • 精确的实例分割标注:每个垃圾实例都使用详细的多边形点进行标注,确保分割边界准确,提升模型训练效果。 • 数据多样性:包含多种垃圾物品实例,覆盖不同场景,增强模型的泛化能力和鲁棒性。 • 格式兼容性强:YOLO标注格式易于与主流深度学习框架集成,如YOLO系列、PyTorch等,方便研究人员和开发者使用。 • 实际应用价值:直接针对现实世界的垃圾管理需求,为自动化环保解决方案提供可靠数据支持,具有重要的社会意义。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值