线段树详解(AWA)

【高级数据结构】影子的宽度(线段树) 目录(进来瞧一瞧) 题目 题目描述 桌子上零散地放着若干个盒子,盒子都平行于墙。桌子的后方是一堵墙。如图所示。现在从桌子的前方射来一束平行光, 把盒子的影子投射到了墙上。问影子的总宽度是多少? 输入 第1行:3个整数L,R,N。-100000 <=L<=R<= 100000,表示墙所在的区间;1<=N<=100000,表示盒子的个数 接下来N行,每行2个... 阅读详情

引入

  问题1 有一列长度为 n n n 的数,刚开始全是 0 0 0 。现在执行 m m m 次操作,每次可以执行一下操作之一:

  1. 将数列中的某个数加上某个数值
  2. 询问给定区间的所有数字的和

题目分析

  根据题目我们很容易想到时间复杂度为 O ( n ) O(n) O(n) 的做法,但是这样做有一个问题,如果 n , m n,m n,m 的值非常大,大概去到 1 0 8 10^8 108 左右,处理的结果往往不那么令人满意。

线段树

  线段树就是一棵二叉树,平衡二叉树。(注意:这里的每个区间都是左封闭右开放)根节点的两个子节点就是自己二分的结果,通过不断的二分,构造出这样一棵树,我们就叫他 线段树 。
线段树

线段树的操作

  线段树,顾名思义,就是一棵树,所以对树的操作线段树也不能少。又因为他是一棵完全二叉树,所以有两种方式储存:静态链表储存和动态指针储存 。

树的储存

// 动态指针储存
struct Node {
    int Left, Right;
    Node *LeftChild, *RightChild;
    int data;  // 外纪(参数awa)
};
// 静态列表储存
#define NN 1000
int c[4*NN] = { 0 };

  这里有个需要注意的地方:为什么c数组的空间需要 4 × N N 4 \times NN 4×NN 呢,因为这是一棵完全二叉树,但是在构建树的时候有可能出现上图这种情况,所以为了满足完全二叉树的要求,我们必须补全这棵树于是需要声明 4 × N N 4 \times NN 4×NN 的空间。

构建树

  构建树的过程也是相当简单QAQ,因为树是由递归定义的,所以我们只需要稍微搞个递归就好啦~

// 建立一棵树
void build(Node* cur, int l, int r) {
    cur->Left = 1;
    cur->Right = r;
    if (l + 1 < r) {
        cur->LeftChild = new Node;
        cur->RightChild = new Node;
        build(cur->LeftChild, l, (l + r) >> 1);
        build(cur->RightChild, (l + r) >> 1, r);
    } else
        cur->LeftChild = cur->RightChild = NULL;
}

修改树

  同样,我们只需要通过递归来修改这棵树就好~~

// 修改树_1
void change(Node* cur, int x, int delta) {
    if (cur->Left + 1 == cur->Right) {
        cur->data += delta;
    } else {
        if (x < (cur->Left + cur->Right) >> 1)
            change(cur->LeftChild, x, delta);
        if (x > (cur->Left + cur->Right) >> 1)
            change(cur->RightChild, x, delta);
        cur->data =
            cur->LeftChild->data + cur->RightChild->data; // 对接点的操作
    }
}

查询树

  有了修改,那么自然要有查询的操作,查询也很简单()。

// 查找区间和
int qurey(Node* cur, int l, int r) {
    if (l <= cur->Left && cur->Right <= r)
        return cur->data;
    else {
        int ans = 0;
        if (l < (cur->Left + cur->Right) >> 1)
            ans += qurey(cur->LeftChild, l, r);
        if (r > (cur->Left + cur->Right) >> 1)
            ans += qurey(cur->RightChild, l, r);
        return ans;
    }
}

例题

  有了上面这些操作,接下来精灵王国请你帮忙解决一些问题(笑~
问题描述
  精灵王的桌子上零散地放着若干个盒子,桌子的后方是一堵墙。如下图所示。现在从桌子的前方射来一束平行光,把盒子的影子投射到了墙上。问影子的总宽度是多少?在这里插入图片描述
输入输出格式
输入格式:
第1行:盒子的个数N(1≤=N≤10000)。
第2…N+1行:每个盒子的起始位置S和结束位置T(1≤S, T≤100000)。

输出格式:
第1行:包含一个整数,表示影子的总宽度。

输入输出样例
输入样例#1:

4
1 2
3 5
4 6
5 6

输出样例#1:

4

加油!聪明的勇士,我相信你可以的!所以我就不写题解啦!再见!

高阶玩法

  恭喜你,你成功解锁了线段树的高阶玩法嘿嘿~。通过上面的分析我们可以知道,线段树基础玩法对每个点的修改和查询和修改时间复杂度是 O ( l o g 2 n ) O(log_2n) O(log2​n) ,确实是个好用的工具,但是!如果我们每次修改一片区间的值,时间复杂度就会去到 O ( n l o g 2 n ) O(nlog_2n) O(nlog2​n) ,还不如我直接暴力模拟呢(怒)。所以 聪明的你 一定想到了,我比你帅,可以通过标记节点来延迟修改来提高效率,这种方法我们把它叫做 lazy-tag。

  我们只需要修改一点代码就能实现这个功能:

  1. 首先是储存部分:
struct Node {
    int Left, Right;
    Node *LeftChild, *RightChild;
    int data;  // 外纪(参数awa)
    int delta; // 延迟修改 <---就是这个东东
};
  1. 然后是修改树和查询树的部分:
// lazy-tag
void update(Node* cur) {
    cur->LeftChild->data +=
        cur->delta * (cur->LeftChild->Right - cur->LeftChild->Left);
    cur->RightChild->data +=
        cur->delta * (cur->RightChild->Right - cur->RightChild->Left);
    cur->LeftChild->delta += cur->delta;
    cur->RightChild->delta += cur->delta;
    cur->delta = 0;
}
// 修改树
void lazy_tag_change(Node* cur, int l, int r, int delta) {
    if (l <= cur->Left && cur->Right <= r) { // 区间被覆盖
        cur->data += delta * (cur->Right - cur->Left);
        cur->delta += delta;
    } else {
        if (cur->delta != 0)
            update(cur);
        if (l < (cur->Left + cur->Right) >> 1)
            lazy_tag_change(cur->LeftChild, l, r, delta);
        if (r > (cur->Left + cur->Right) >> 1)
            lazy_tag_change(cur->RightChild, l, r, delta);
        cur->data =
            cur->LeftChild->data + cur->RightChild->data; // 对接点的操作
    }
}
// 查询树
int lazy_tag_qurey(Node* cur, int l, int r) {
    if (l <= cur->Left && cur->Right <= r)
        return cur->data;
    else {
        if (cur->delta != 0)
            update(cur);
        int ans = 0;
        if (l < (cur->Left + cur->Right) >> 1)
            ans += lazy_tag_qurey(cur->LeftChild, l, r);
        if (r > (cur->Left + cur->Right) >> 1)
            ans += lazy_tag_qurey(cur->RightChild, l, r);
        return ans;
    }
}

  这里我稍微的解释一下,这里每次扫描,只要扫描到左右区间能完全覆盖到的地方,就可以直接返回了,剩下了很多的不必要的计算,再在查询的时候直接更新,再加上就好。到这里,你的不承认,我真的比你帅你真的很聪明。

撤退!再见!

【信息学CSP-J近16年历年真题64题】真题练习与解析 第9题之数字游戏 信息学CSP入门级历年真题训练之数字游戏,考点:字符串 阅读详情

相关推荐

主流仿真软件Sigrity/HFSS/Siwave/Hyperlynx/ADS差异

在电子设计自动化(EDA)领域,各种仿真软件如Cadence Sigrity、Mentor Graphics的HyperLynx、Keysight的ADS以及ANSYS的SIwave等,都广泛应用于不同的应用场景中。综上所述,这些EDA仿真软件在各自的应用场景中发挥着重要作用,帮助工程师在设计阶段就能够评估和优化电子产品的性能,提高设计的可靠性和效率。:Sigrity由全球最大的EDA公司Cadence推出,Cadence还推出了Orcad和Allegro等著名软件。:由安捷伦(现是德科技)公司开发。

Geektec的专栏 9402

蓝桥杯 C++项目题库7

例如,当 n = 4 时,有以下 6 种方案:1×1×4、1×2×2、1×4×1、2×1×2、 2 × 2。A1={1,2,4},A2={3,5},其中 A1 的和为 7,A2 的和为 8,和的差值等于 1。A1={1,3,4},A2={2,5},其中 A1 的和为 8,A2 的和为 7,和的差值等于 1。A1={3,4},A2={1,2,5},其中 A1 的和为 7,A2 的和为 8,和的差值等于 1。对于所有评测用例,1 ≤ n, m ≤ 100000,0 ≤ ai ≤ 1,1 ≤ bi ≤ n。

c++练习生 2397

利用ArcGIS创建渔网计算渔网内土地利用占比划分中国北方农牧交错带

依据土地利用数据,根据参考文献划分要求,利用ArcGIS创建渔网对地物进行重分类,划分农业带、牧业带以及农牧交错带。

m0_60672527的博客 3059

线段树

线段树 想学主席树,然后开了一篇题解,看到“学习可持久化线段树之前一定要学懂线段树”这句话我只好把线段树又学了一遍(( 这块从昨天到今天学了四个小时,做了三页纸笔记,所以有错的可能性不大(但是wtcl,所以还是有可能的 概括 线段树的理解,按照书上的(( 线段树的每个节点都代表一个区间; 线段树具有唯一的根节点,代表的区间是整个统计范围; 线段树的每个叶节点都代表一个长度为1的元区间[x,x]; 对于每个内部节点[l,r],它的左子节点是[l,mid],右子节点是[mid+1,r],其中mid=(l+r)

weixin_46704467的博客 567

Brim与ZUI协同安装指南:从下载到流量分析实战

本文提供Brim与ZUI协同安装与实战指南,详细讲解从下载、环境变量配置到流量分析的全流程。通过将PCAP文件转换为ZNG格式,结合直观的Zed查询语言,这套组合能极大提升大型网络数据包的分析效率,是网络安全与运维人员进行高效流量分析的利器。

metal的博客 458

从脑电到脑机接口:EEG/ERP特征如何驱动你的下一个智能硬件项目(Arduino/树莓派实战)

本文详细介绍了如何利用EEG/ERP特征提取技术驱动智能硬件项目,涵盖从脑电信号采集到脑机接口实现的完整流程。通过Arduino和树莓派实战,展示了P300、N400等事件相关电位的应用,帮助开发者将学术理论转化为可编程的交互指令,适用于智能家居、医疗辅助等领域。

weixin_29279047的博客 383

手把手教你写线段树

我争取写一篇对刚入门的新手友好的文章对线段树加以说明,手把手教大家写线段树。

单精度的梦 2956

10万张数据集持续迭代:YOLO模型的场景专属自进化体系如何搭建?

做工业质检的朋友应该都有过这样的经历——拿着在COCO上刷榜的YOLO模型跑到产线上一测,精度直接腰斩。这不是模型不行,是场景不对口。过去一年,我深度参与了一个工业视觉项目:产线每天产生超过10万张图像,需要持续迭代检测模型。我们踩过无数坑,最终摸索出一套YOLO模型的场景专属自进化体系。今天不聊虚的,直接上干货。让模型在真实场景数据中持续学习、自动进化,而不是每次依赖人工标注从头训练。下面我从主动学习筛选、增量持续学习、架构选型、部署优化、安全防护五个维度,拆解整个搭建过程。声明。

2601_95807009的博客 106

POJ 2352 Stars 【线段树】

题目来源:http://poj.org/problem?id=2352 ★这题我一开始题目都理解不了awa 后来经过同学指点才知道意思 但是知道也没用 还是不会写~ 题意: 大概就是输出 0 到 n-1 level层所有的点数,一个点的左下方(包括左下的线上)有多少个点就是多少层 思路: 以x轴为线 建树(不知道说的规范不),要边输入边更新点,因为如果你一次性的把点更新完了 ...

HungTeen的博客 233

ASP.NET Core 6 Web API在IIS上的部署与调试

通过以上步骤和配置,你应该能够成功部署并调试你的ASP.NET Core 6 Web API在IIS上。记住,权限和配置是关键,确保你的环境和应用程序代码都正确设置。希望这篇博客对你部署和解决IIS上的问题有所帮助。

m0_74337424的博客 522

YOLO11改进|YOLO11中引入注意力和卷积融合模块CAFMAttention

YOLO11改进|YOLO11中引入注意力和卷积融合模块CAFMAttention

A1983Z的博客 1220

NOI数据结构:二维线段树

二维线段树专题 二维线段树专题_wangheng-优快云博客_二维线段树 二维线段树 - 英雄哪里出来 - C++博客 UVA 11297 线段树套线段树(二维线段树)_园荐_博客园 浅谈二维线段树 浅谈二维线段树 - TRTTG - 博客园 POJ 2155 Matrix (二维线段树) POJ 2155 Matrix (二维线段树)_每一次AC都是一种感动-优快云博客 [luogu3397]地毯(二维线段树组) [luogu3397]地毯(二维线段树组)_fl_334正

青少年趣味编程 467

爬取B站评论+AI情感分析:Python批量抓数据+BERT正负向分类(全流程)

B站作为年轻群体聚集的内容平台,评论区蕴含海量用户真实态度(如好评、吐槽、中立观点),是情感分析的优质数据源!本文分享完整流程:批量爬取B站视频评论→数据清洗去噪→BERT模型情感分类→可视化分析,基于预训练BERT模型实现高精度正负向判断,新手也能快速复刻情感分析系统! 前置配置(关键!获取B站API访问权限) B站评论通过官方API接口返回,无需复杂解析,只需配置用户Cookie即可正常请求: 2. 完整代码(直接复制运行) 三、使用步骤(5步搞定,新手友好) 步骤1:配置关键参数 打开,在类中修改

专注于Python爬虫开发,分享爬虫技巧、项目实战与反爬经验,使用Scrapy、BeautifulSoup等工具,解决数据抓取难题。 1068

P4770:你的名字(SAM、线段树合并)

SAM毒瘤题

BUG_Creater_jie的博客 287

Outlook Express 6 (OE6) for Win7/Win8/Win10

英文版 Outlook Express6.0, 兼容Win7/Win10/WinXP,解压就可用。

visio安装包

Microsoft Office Visio 是一款专业的制图软件。利用经过更新的形状、协作工具和数据链接图表,创建专业级图表以简化复杂的信息。

Codeforces Beta Round #19 D 【线段树】

题目来源:https://codeforces.com/contest/19/problem/D ★一两个星期没写线段树了,第一题就不会awa ~ 题解使用了 C++ STL库 中的 set (集合) 翻译: 在一个以(0,0)为原点的二维坐标系下,x轴向右,y轴向上。现在有三种操作,①:增加一个点;②:删去一个点;③:询问一个点(x,y),询问时,找(x,y)右上方 的所有点中 先尽可能靠...

HungTeen的博客 230

老版QQ原生表情gif动态

这是老版的QQ表情,不过全是动态的的,Windows照片查看器是不会动的,可以右击用浏览器打开查看,再说一遍是老版的,只是分享给宁愿用老版也要动态的人。

[BZOJ4373算术天才⑨与等差数列] 线段树

[BZOJ4373算术天才⑨与等差数列] 线段树分类:Data Structure1. 题目链接[BZOJ4373算术天才⑨与等差数列]2. 题意描述算术天才⑨非常喜欢和等差数列玩耍。 有一天,他给了你一个长度为n的序列,其中第i个数为a[i]。 他想考考你,每次他会给出询问l,r,k,问区间[l,r]内的数从小到大排序后能否形成公差为k的等差数列。 当然,他还会不断修改其中的某一项。 为了

Fighting! 714

android 蓝牙通讯demo

android 下蓝牙通讯demo,实现了发现蓝牙,使能蓝牙,通过蓝牙发送消息。

loj 523 「LibreOJ β Round #3」绯色 IOI(悬念) 霍尔定理+基环树+线段树

题目分析 神仙题(确信) 首先,j−aij-a _ ij−ai​和ai−ja _ i-jai​−j互为相反数,若其中最小值为bib _ ibi​,则一个为bib _ ibi​一个为m−bim-b _ im−bi​。(以下运算均在模mmm意义下进行) j−ai=bij-a _ i = b _ ij−ai​=bi​即j=ai+bij= a _ i + b _ ij=ai​+bi​ ai−j=bia _...

litble的成(tui)长(fei)史 703

TYOI集训日记

"我们永远无法预知某一个瞬间的价值,直到它成为我们的回忆"

Q_Linda的博客 433

8.16模拟:树上算法

文章目录前言收获全排列求期望模型转化树哈希判断同构&无根同构转有根同构比赛复盘T1 reformT2 buildT3 relationT4 split总结 前言 150分 100+20+30+0 qwq 今天题还是较难 而且又去打了半个多小时的疫苗 情有可原吧 T2其实是可切的 T3的暴力因为数组开小了挂了30qwq 感觉这几天是要把所有低级错误都犯一遍的节奏… 明天要集中注意力!awa 收获 全排列求期望 神仙思路,学会了 模型转化 这个一时半会可能收获不了… 不过应该有意识的锻炼相关思维 树哈希

BUG_Creater_jie的博客 197

8.17模拟:数学

文章目录前言收获考场复盘T1T2T3T4总结 前言 190分 60+100+30+0 虽然分不太高,但毕竟今天的题有点太阴间了… 所以还不错啦 最重要的是今天挂分很少 终于停住了这几天越挂越嗨的态势 也就T4挂了5分吧,可以接受 收获 算斜率的区间确定一条线旋转位置时要取斜率的倒数,可以解决正负无穷之类的奇怪问题 卡特兰数:c[n]=(2n)!/(n!∗(n+1)!)c[n]=(2n)!/(n!*(n+1)!)c[n]=(2n)!/(n!∗(n+1)!) 考场 啊今天8:30开考 先看题 万念俱灰… 感

BUG_Creater_jie的博客 248

[nK] 又一数区间问题 暴力统计,贪心优化

前言 太简单了吧,就debug难而已 传送门: https://ac.nowcoder.com/acm/contest/11215/E 思路 一开始区间问题想到的是 线段树,RMQ,树状数组.但是看完题目之后 发现维护的是 区间乘积, 查询是 logn 然后枚举区间 nlogn 因此理论可行 但是我不会写awa 因为此题给的是 1-9不难想到 是 string 字符 所以我们可以通过枚举左端点 O n 但是这么算下来不就是 O n^2 的了 ? 因此我们可以优化 区间长度1e5 所有都是1的话 那么会

qq_34364611的博客 244

CSP-J/S 2020 游记

CSP-J/S 2020 游记

Hardy_Lee的博客 826

Summer training round2 #4 (Training #20)

A!:UESTC1752 B!:找区间内L到R之间内的数的个数 权值分块加莫队 C!:给你一个哈斯图 去掉其中的几条边 要求输出字典序最大的拓扑排序:线段树模拟拓扑排序 D!:要求你找到最短路树并输出 E:SG函数 F:求出偶数和奇数的个数套公式 G:要求你从两个set里找出符合要求两个数 找规律 I:找规律 用二进制模拟生成的规律 J:找规律 直接暴力模拟次数%周期后...

baichuan9723的博客 136

CQ NOIP2021 + CSP—J 奇人合集

这篇文章中会有说 CQ 有 27名选手提到fuck,贴出了 8个含有fuck的程序。如果你是写这些程序的选手,请告诉我,我会撤下的,我不希望因为没有撤下而带给您麻烦。还是比 @XSC062 慢了一步(使用 VSC 进行统计。本次 NOIP CQ 得到的代码中最高编号为 322,实际提交代码成功的选手为 322人。在 1218个文件中有 2277 个include。意思就是说,有 70 个完全没动的题。(指实际得到的文件比应该得到的少 70 个)只有 857个万能头文件。

Chat_lsm2024的博客 1393

数据结构--柯朵莉树

一道例题,先跳过qwq 题目链接 题目描述 lxhgww最近收到了一个01序列,序列里面包含了n个数,这些数要么是0,要么是1,现在对于这个序列有五种变换操作和询问操作: 0 a b 把[a, b]区间内的所有数全变成0 1 a b 把[a, b]区间内的所有数全变成1 2 a b 把[a,b]区间内的所有数全部取反,也就是说把所有的0变成1,把所有的1变成0 3 a b 询问[a, b]区间内总...

QAQ 527

洛谷P3655 不成熟的梦想家 (未熟DREAMER)

链接:P3655 题目有点复杂,直接点链接吧。 有水团awa 虽然难度只有黄色,但是我还是来做了这道树状数组水题awa 对于题目中的对于x到z的成员都加上一个值z,当时脑子里飘过的想法,不是线段树就树状数组(因为俺只会这两个) 因为用线段树应该也可以做,时间急促我以后会慢慢补的。 这里先主要说一下我利用树状数组写的过程 树状数组维护一个差分数组进行区间修改区间求和 然后对于魅力值,我们可以首先算...

秃头交易站. 517
上一篇: 离散化思想详解
下一篇: 关于Visual Studio C++相对路径的问题
ResCells
博客等级 码龄4年 191粉丝 26原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值