数据结构 线段树

【c++提高1】数据结构之线段树详解 线段树的思想是将一个区间[1, n]划分成两个区间: [1, n/2]和[n/2+1, n],接下来继续划分: [1, n/4], [n/4+1,n/2]和[n/2+1, n/2+n/4-1], [n/2+n/4,n] …示例:n = 81.pushup函数2.pushdown3.build4.modify5.query1.线段树的儿子存储2.线段树的节点信息存储 定义一个结构体,里面存储改节点信息和当前这个节点所管辖的区间的左右端点。1.建树函数build 递归建树。 怎样判断当前节点是叶子节点呢?2.查 阅读详情

线段树

解决的问题

  • 区间的最大值
  • 区间的最小值
  • 区间的总和

操作

  1. push up 操作

由子节点来算父节点的信息 sum = l.sum + r.sum

void pushup(int u) // 待更新的节点

  1. push down 操作(懒标记/延迟标记)

由父节点的信息下降到子节点

void pushdown(int u)

  1. build操作

将一段区间初始化成一个线段树

build(int u, int l, int r) // 待建立的节点, 区间的左端点, 区间的右端点

  1. modify操作
    1. 修改一个点
    2. 修改一个区间 (需要用到push down操作)

modify(int u, int x, int v) // 待更新的节点u, 被更新的点x, 被修改的值v

  1. query操作

查询操作

query(int u, int l, int r) // 待查询的节点u, 被查询的左端点l, 右端点r

原理

时间复杂度 O ( 4 l o g ( n ) ) O(4log(n)) O(4log(n))

**特点 **除了最后一层的节点以外, 是一个满二叉树

存储方式 用一维数组来存整棵树

编 号 是 x = { 父 节 点 = ⌊ x 2 ⌋ x > > 1 左 儿 子 = 2 x x < < 1 右 儿 子 = 2 x + 1 x < < 1 ∣ 1 编号是x = \left\{ \begin{aligned}&父节点 = \lfloor \frac{x}{2} \rfloor & x >>1\\&左儿子 = 2x & x<< 1\\&右儿子 = 2x+1 &x << 1|1\end{aligned} \right. 编号是x=⎩⎪⎪⎨⎪⎪⎧​​父节点=⌊2x​⌋左儿子=2x右儿子=2x+1​x>>1x<<1x<<1∣1​

题目示例

最大数

给定一个正整数数列 a1,a2,…,an,每一个数都在 0∼p−1 之间。

可以对这列数进行两种操作:

添加操作:向序列后添加一个数,序列长度变成 n+1;
询问操作:询问这个序列中最后 L 个数中最大的数是多少。
程序运行的最开始,整数序列为空。

一共要对整数序列进行 m 次操作。

写一个程序,读入操作的序列,并输出询问操作的答案。

输入格式
第一行有两个正整数 m,p,意义如题目描述;

接下来 m 行,每一行表示一个操作。

如果该行的内容是 Q L,则表示这个操作是询问序列中最后 L 个数的最大数是多少;

如果是 A t,则表示向序列后面加一个数,加入的数是 (t+a) mod p。其中,t 是输入的参数,a 是在这个添加操作之前最后一个询问操作的答案(如果之前没有询问操作,则 a=0)。

第一个操作一定是添加操作。对于询问操作,L>0 且不超过当前序列的长度。

输出格式
对于每一个询问操作,输出一行。该行只有一个数,即序列中最后 L 个数的最大数。

数据范围
1 ≤ m ≤ 2 × 1 0 5 , 1 ≤ p ≤ 2 × 1 0 9 , 0 ≤ t < p 1≤m≤2×10^{5}, 1≤p≤2×10^{9}, 0≤t<p 1≤m≤2×105,1≤p≤2×109,0≤t<p
输入样例:

10 100
A 97
Q 1
Q 1
A 17
Q 2
A 63
Q 1
Q 1
Q 3
A 99

输出样例:

97
97
97
60
60
97

样例解释
最后的序列是 97,14,60,96。

代码

#include<iostream>
#include<cstring>
#include<algorithm>
#include<cstdio>

using namespace std;
typedef long long LL;
const int N = 200010;

int m, p;
struct Node {
    int l, r;
    int v;         // 区间[l, r]的最大值
}tr[N * 4];

void pushup(int u) { // 由子节点的信息来计算父节点的信息
    tr[u].v = max(tr[u << 1].v, tr[u << 1 | 1].v);
}

void build(int u, int l, int r) {
    tr[u] = {l, r};
    if (l == r) return;
    int mid = l + r >> 1;
    build(u << 1, l, mid), build(u << 1 | 1, mid + 1, r);
}

int query(int u, int l, int r) {
    if (tr[u].l >= l && tr[u].r <= r) return tr[u].v;

    int mid = tr[u].l + tr[u].r >> 1;
    int v = 0;
    if (l <= mid) v = query(u << 1, l, r);
    if (r > mid) v = max(v, query(u << 1 | 1, l, r));
    return v;
}

void modify(int u, int x, int v) {
    if (tr[u].l == x && tr[u].r == x) tr[u].v = v;
    else {
        int mid = tr[u].l + tr[u]. r >> 1;
        if (x <= mid) modify(u << 1, x, v);
        else modify(u << 1 | 1, x, v);
        pushup(u);
    }

}

int main() {
    int n, last = 0;
    scanf("%d%d", &m, &p);
    build(1, 1, m);

    int x;
    char op[2];
    while (m--) {
        scanf("%s%d", op, &x);
        if (*op == 'Q') {
            last = query(1, n - x + 1, n);
            printf("%d\n", last);
        }
        else {
            modify(1, n + 1, ((LL)last + x) % p);
            n++;
        }
    }

}
数据结构:二维线段树 顾名思义,二维线段树就是在一棵线段树的每一个节点,都保存着另一棵线段树的根节点编号。二维线段树通常支持以下2种功能:1、单点修改;2、二维区间查询。为了实现这两种功能,我们需要建一棵外层线段树(可以动态开点也可以静态开点),对于外层线段树的每一个节点,我们都保存一个内层线段树的根节点编号(内层线段树必须动态开点,否则MLE)。代码:#define sz 100000 struct hh { ... 阅读详情

相关推荐

IQA图像质量评价 数据集介绍(LIVE、TID2013、CSIQ、LIVEC、KonIQ-10K)

LIVE、TID2013、CSIQ、LIVEC、KonIQ-10K 数据集介绍

qq_37925923的博客 1万+

1549:最大数——线段树

【题目描述】原题来自:JSOI 2008给定一个正整数数列 a1,a2,a3,⋯,an ,每一个数都在 0∼p–1 之间。可以对这列数进行两种操作:添加操作:向序列后添加一个数,序列长度变成 n+1;询问操作:询问这个序列中最后 L 个数中最大的数是多少。程序运行的最开始,整数序列为空。写一个程序,读入操作的序列,并输出询问操作的答案。【输入】第一行有两个正整数 m,p,意义如题目描述;接下来 m 行,每一行表示一个操作。

与其邻渊羡渔,不如退而结网 1290

QMI8658姿态传感器实战:从校准到自检的完整避坑指南

本文详细解析了QMI8658姿态传感器的校准与自检流程,提供了从硬件环境搭建到高级功能开发的完整避坑指南。通过真实案例揭示电源设计、接口优化、温度补偿等关键细节,帮助开发者提升传感器精度和可靠性,适用于工业级应用场景。

weixin_29184075的博客 456

1549:最大数

【题目描述】 原题来自:JSOI 2008 给定一个正整数数列 a1,a2,a3,⋯,an ,每一个数都在 0∼p–1 之间。可以对这列数进行两种操作: 添加操作:向序列后添加一个数,序列长度变成 n+1; 询问操作:询问这个序列中最后 L 个数中最大的数是多少。 程序运行的最开始,整数序列为空。写一个程序,读入操作的序列,并输出询问操作的答案。 【输入】 第一行有两个正整数 m,p,意义如题目描...

叶上初阳_285557的博客 997

单细胞转录组数据分析全流程:从原始数据到细胞注释

本文详细介绍了单细胞转录组数据分析的全流程,从原始数据读取、环境搭建、数据质控与标准化,到降维聚类、细胞类型注释,以及高级质控与多样本整合。重点阐述了如何利用Seurat等工具进行数据处理,并通过标志基因比对与自动注释方法完成细胞身份鉴定,为研究者提供了一套清晰、可操作的分析指南。

coffee的博客 553

Python全栈入门到实战【基础篇 22】生成器与迭代器:底层逻辑与实战场景

Python迭代器与生成器:惰性求值的高效实践 摘要:本文深入解析Python中迭代器和生成器的核心机制与应用场景。迭代器通过实现__iter__()和__next__()方法实现惰性求值,适合处理大数据集和无限序列。生成器作为迭代器的简化实现,通过yield关键字自动实现迭代器协议,代码更简洁。文章详细对比了可迭代对象与迭代器的区别,演示了自定义迭代器和生成器函数的实现方式,并介绍了生成器表达式这一高效替代列表推导式的方案。通过斐波那契数列等实例,展示了惰性求值在内存优化方面的优势,以及生成器在流式数据处

那些看似不起波澜的日复一日,会在某天让你看到坚持的意义 3263

AcWing. 1275 最大数 (单点修改 + 区间查询)

AcWing. 1275最大数 给定一个正整数数列 a1,a2,…,an,每一个数都在 0∼p−1 之间。 可以对这列数进行两种操作: 添加操作:向序列后添加一个数,序列长度变成 n+1; 询问操作:询问这个序列中最后 L 个数中最大的数是多少。 程序运行的最开始,整数序列为空。 写一个程序,读入操作的序列,并输出询问操作的答案。 输入格式 第一行有两个正整数 m,p,意义如题目描述; 接下来 m 行,每一行表示一个操作。 如果该行的内容是 Q L,则表示这个操作是询问序列中最后 L 个数的最大数是多少

zzqwtc的博客 3043

SPAD IMX479规格_分辨率

当然IMX479具备IMX459几乎全部的数字架构,但也有一个缺点就是贵,这个让头部的主机厂有些犹豫,毕竟大家都在集中火力想把车载LiDAR玩进千元机。如果用一片IMX479是不太可能实现千元内部的,当然国产也在奋起直追,特别在前面的几家SPAD厂商都具备开发IMX479的实力,但相对来说落地可能更是当下所考虑的,IMX479的迭代是基于IMX459,小编已经注意到国内有一两家已经在挑战479的规格了,如果国产SPAD没有大规模量产就直接流片IMX479的规格,可能就有点忽略市场的反馈闭环。

致力于lidar应用开发 2418

1549:最大数(线段树模板)---信息学奥赛一本通

【代码】1549:最大数(线段树模板)---信息学奥赛一本通。

陈进士学习的博客 732

如何成为一名高级数字 IC 设计工程师(6-7)数字 IC 验证篇:DEBUG 技巧

不懂验证的设计不是好的设计;UVM 验证思维是指导缜密的芯片设计的导师;推荐书籍《芯片验证漫游指南》。

新芯设计的博客 1606

机器人轨迹规划——梯形速度轨迹(超详细)

机器人轨迹 这一系列轨迹教程将主要包括以下内容: 点到点轨迹(P2P) 五次多项式插值轨迹 三次多项式插值轨迹 梯形速度曲线轨迹 双S形速度曲线轨迹 多个自由度轨迹的时间同步 在线轨迹规划 多项式在线轨迹规划 梯形在线轨迹规划 双S形在线轨迹规划 非线性实时轨迹滤波 多点轨迹(Multi-point) 三次样条曲线(cubic spline) 贝赛尔曲线(Bezier Curve) B样条曲线(BSpline) 时间最优轨迹 三次样条时间最优轨迹 任意路径下的时间最优轨迹 时间

出门搔白首,若负平生志 1万+

loj 10127最大数

JSOI 2008 最大数 给定一个正整数数列a1​,a2​,a3​,⋯,an​,每一个数都在0∼p–1之间。可以对这列数进行两种操作: 添加操作:向序列后添加一个数,序列长度变成n+1; 询问操作:询问这个序列中最后L个数中最大的数是多少。 程序运行的最开始,整数序列为空。写一个程序,读入操作的序列,并输出询问操作的答案。 输入格...

weixin_30823001的博客 280

K8S搭建(centos)四、安装K8S

每个人都有惰性,但不断学习是好好生活的根本,共勉!

感谢阅读 2653

【数据结构】-线段树

线段树(Segment Tree)是一种数据结构,它主要用于维护区间信息(要求满足结合律),它可以实现 𝑂(log⁡𝑛) 的区间修改,还可以同时支持多种操作(加、乘)。从数据结构的角度来说,线段树是用一个完全二叉树来存储对应于其每一个区间(segment)的数据。该二叉树的每一个结点中保存着相对应于这一个区间的信息。同时,线段树所使用的这个二叉树是用一个数组保存的,与堆(Heap)的实现方式相同。例如,给定一个长度为N的数组arr,其所对应的线段树TT的根结点代表整个数组所在的区间对应的信息,及。

knoci的博客 1931

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

汉书HE8,好用的汇编代码编写工具

汉书HE8,好用的汇编代码编写工具早期编写汇编代码所用功能强大

数据结构 线段树--权值线段树 详解

一、权值线段树 简介 1.线段树 线段树是一种用于维护区间信息的高效数据结构,可以在 O(log⁡N)O(\log N)O(logN) 的时间复杂度内实现单点修改、区间修改、区间查询(区间求和,求区间最大值,求区间最小值)等操作。 线段树维护的信息必须满足可加性,即能以可以接受的速度合并信息和修改信息,包括在使用Lazy标记时,标记也要满足可加性 具体有关线段树的的讲解请参考博客:线段树 详解与模板

HeartFireY的博客 1万+

VB摄像头监控

该VB模块可对摄像头捕获的画面进行录像等,可在创建的窗口进行控制

C++数据结构·线段树

线段树是一种高效处理区间操作的数据结构,支持区间查询和区间更新,时间复杂度均为O(log n)。其核心是通过二叉树预处理区间信息,叶子节点存储原始数据,非叶子节点存储子区间合并结果(如区间和、最值)。与普通二叉树不同,线段树节点表示区间范围而非单一数据,适合动态区间统计问题。模板代码包含建树、懒标记下传、区间查询和更新操作,典型应用如洛谷P3372题解所示,通过线段树实现区间加减和求和功能,4倍空间预处理是关键。注意不适用于非区间类问题或频繁全量重建场景。

Gohldg的博客 3289

计算机控制技术及应用

《计算机控制技术及应用》通过总结作者的科研成果和吸收国内外的先进理论、方法和技术,以计算机控制系统的网络化、开放化、智能化和集成化发展趋势为主线索,主要介绍计算机控制系统的基本概念和计算机控制系统的典型形式,计算机控制系统的数学描述与基本分析方法,以及数字PID控制器、最少拍控制系统、达林算法、状态变量设计法等设计方法及其各种改进算法。重点突出计算机控制系统输入输出通道接口的设计方法和典型控制系统的设计案例与实现方法等。

【数据结构】线段树

【数据结构】线段树 问题 最后一次用到线段树,是在深圳老东家实习面试的时候,Jason 问到我的一个问题(具体问题不记得了,大致意思): 一个固定大小 n 的有限数组 x action 1 : 可以随时更新某个区间 [i, j] 内的元素 action 2 : 可以查询某个区间 [i, j] 内的最大值或最小值 你应该如何做? 简单的解法 1 ? 普通数组形式存储,额外空间消耗 O(1)...

描绘自己的王国…… 1383

数据结构:线段树

已迁往:http://www.iteblog.com/archives/144一、线段树基本概念           线段树是一种二叉搜索树,与区间树相似,它将一个区间划分成一些单元区间,每个单元区间对应线段树中的一个叶结点。    对于线段树中的每一个非叶子节点[a,b],它的左儿子表示的区间为[a,(a+b)/2],右儿子表示的区间为[(a+b)/2+1,b]。因此线段树是平衡二叉树,最后的子

过往记忆大数据 11万+

[数据结构]线段树

线段树 一听到树,估计很多人会觉得头疼,因为树形结构算是一种比较难的数据结构了,有一系列的公式啊,概念啊什么的,代码实现也是比较麻烦。但其中也有一些很基础,很好实现近乎模板的数据结构。前面的树状数组是一种,这里的线段树也是这样的一种。 与树状数组的区别 树状数组的话可以说相对做法较为单一,要么是单点修改,区间查找,要么是区间修改,单点查找,不这样的话几乎是要爆炸的。除非用什么进阶方法,反正我...

ywy 252

数据结构 - 线段树

数据结构 - 线段树

qq_43350524的博客 688

ACMer不得不会的线段树,究竟是种怎样的数据结构?

大家好,欢迎阅读算法数据结构专题,今天我们来聊聊一个新的数据结构,叫做线段树。 线段树这个数据结构很多人可能会有点蒙,觉得没有听说过,但是它非常非常有名,尤其是在竞赛圈,可以说是竞赛圈的必备技能。所以如果以后遇到有人看了一点算法导论就在你面前装逼,你就可以问他:请问线段树更新的复杂度是多少? 不过如果你会线段树,你也要小心一点,最好不要在面试的时候随便透露你会这个算法。否则面试官一下子就会知道你是圈里人,然后你会发现你后面的面试问题比之前好像难不少。当然也有可能遇到面试官自己不会,为了防止尴尬强行让你用非线

TechFlow的博客 580

数据结构之线段树

目录 线段树(区间树)Segment Tree 线段树的概念 为什么要使用线段树 手写一个线段树 线段树中的区间查询 线段树问题 LeetCode303 LeetCode307 对区间进行操作的时间复杂度 线段树(区间树)Segment Tree 线段树的概念 线段树是一种特殊的树结构。这种数据结构主要用于解决“线段”或者是“区间”这种特殊的数据 线段树是一种二叉搜...

万物并作,吾以观复 2615

【数据结构】 线段树

……线段树可是一个高端的东西。 一、啥是线段树 信息迅速发端的现在,人们已经发明出一个又一个算法以及数据结构。当人们嫌人眼校对会有错误,又会引起眼神疲劳时,人们发明了KMP;当人们嫌前缀和麻烦,效率不够,不能修改时,人们想到了树状数组;当人么又嫌树状数组只能单点修改不能区间修改时,人们,人们,人们,又想到了———— 线段树线段树线段树 没错,线段树就是一个支持区间修改和区间查询的一个高级数据结构...

鹭天 264

线段树数据结构详解

线段树数据结构详解 Coded by Jelly_Goat. All rights reserved. 这一部分是线段树。 线段树,顾名思义,是一种树形数据结构,适用于各种求区间统一算法的动静两平衡的数据结构。 这里什么是统一算法?(自己口胡的统一算法) 比如求最大值or最小值、区间求和,一样的区间都是一样的算法,这也是和动态dp不同的地方。 前置知识1:二叉搜索树 二叉搜索树就是根节...

anita_2014的博客 311

活用各种数据结构——线段树篇

对《挑战程序设计竞赛》的一个记录第三章 出类拔萃——中级篇3.3活用各种数据结构——线段树篇下一篇:3.3活用各种数据结构——RMQ/树状数组/分桶法和平方分割线段树主要还是看胡浩的文章 (完全版线段树)- 单点更新以下代码块的头文件”head.h” 的代码如下,不再重复黏贴#include "cstdlib" #include "cctype" #include "cstring" #inclu

loveyzhou的专栏 1790

线段树——数据结构的克星

#include<bits/stdc++.h> using namespace std; const int maxn=1e5; struct node{ int e; // int l,r; int lazy; node() { e=lazy=0; } // int mid(){ // return (r+1)>>1; // } }tree[maxn&lt...

weixin_43310882 2987
上一篇: 算法笔记 差分约束
下一篇: 排序(快排 + 归并)
ghost_him
博客等级 码龄6年 598粉丝 90原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值