python线段树编写

  • 前言
  • 一、题目及代码编写
  • 二、补充说明
  • 三、总结

前言

  • 以LC 729. 我的日程安排表 I 为例
  • 这道题不推荐使用这种解法 非常的慢,而且代码超级容易记错!
  • 你没看错 记错!

提示:以下是本篇文章正文内容,下面案例可供参考

一、题目及代码编写

(1)题目简单说一下


(2)字典树编写

  • 这里代码非常长 我们分开说 想要更直观学习线段树的朋友可以去看一下前几年黄浩杰大神关于线段树的讲解,用的是C语言很好理解,我只能说大神讲得非常棒!
    字典树的编写主要分成四部分,我们现在逐一来说:
  1. 数据结构的定义
      这里推荐用树的结构,这里有一个懒标记的定义,其实我刚开始看到这个懒标记也非常的头疼,找一个视频就会说,你先看一下我其他的基础视频讲解,很无语啊!在这里我提前说一嘴:节点处的懒标记就是更新过程中子树需要完成的数据操作(加减)被预先存放在一起,当查询到该节点的子树时,懒标记下放到子树完成子树的数据更新。
      可能,我自己说出这话的时候我都不相信这是我说的,推荐大家去B站搜一搜线段树,现在的大部分讲解在懒标记的概念上解释都非常到位,重点是:耐心一点。
      下面是数据结构的定义,注释写得很详细了。
class Node:def __init__(self):# 左右子树self.left = Noneself.right = None# 当前节点的值self.val = 0# 更新时,子树的增量标记self.add = 0
  1. 字典树的编写 主要有:向下动态开点和懒标记维护、更新操作、查询操作
      这里的动态开点,直观理解就行,没那么高大上,就是需要子树了,就给加上的意思,懒标记维护就是:结点往下走的过程中你要一直背着这个操作,画个图说明一下。
class MySegment:def __init__(self,size):self.size = sizeself.node = Node()return# 向下动态开点和懒标记维护def pushDown(self,node: Node,leftNums: int, rightNums: int):'''node        当前节点leftNums    左子树所含节点个数rightNums   右子树所含节点个数'''# 动态开点if node.left is None: node.left = Node()if node.right is None: node.right = Node()# 如果 增量标记为0 直接返回if node.add == 0: return # 如果 增量标记不为0 需要进行累加操作node.left.val += node.addnode.right.val += node.addnode.left.add += node.addnode.right.add += node.add# 完成加操作后 记着去掉add标记node.add = 0# 更新操作def update(self,node: Node, start: int,end: int,L: int, R: int,adds: int):'''node    当前节点start   节点所代表区间的左边界end     节点所代表区间的有边界L       所修改的区间左边界R       所修改的区间的右边界adds    修改区间的增量'''if L <= start and end <= R:# 如果修改的区间 包裹着修改节点所代表的区间 直接对该节点的val和add进行操作node.val  += addsnode.add += addsprint(node.val)returnmid = (start + end) // 2# 有关pushDown的建立有点水 后两个数好像用处不是特别大self.pushDown(node,mid - start + 1,end - mid)# 进入左子树 对应的查询边界变为 [start,mid]if (L <= mid): self.update(node.left,start,mid,L,R,adds) # 进入右子树 对应的查询边界变为 [mid+1,end]if (R > mid): self.update(node.right,mid+1,end,L,R,adds)# 记住最后更新节点值node.val = max(node.left.val, node.right.val)# 查找操作def query(self,node: Node,start: int,end: int,L: int, R: int):'''node    当前节点start   节点所代表区间的左边界end     节点所代表区间的有边界L       所查询的区间左边界R       所查询的区间的右边界'''# 如果所查询的区间包含了节点所表示区间 直接对该节点的val进行操作if L <= start and  end <= R:return node.val# 继续上面的套路 找中点mid,ans = (start+end) // 2,0# 这个点找不到 往下压一个点self.pushDown(node,mid-start+1,end-mid)# 同样递归判断 该去那个区间找值if L <= mid: ans = self.query(node.left,start,mid,L,R)if R > mid: ans = max(ans,self.query(node.right,mid+1,end,L,R))return ans

(3)完成题目需要的主函数编写

 class MyCalendar:def __init__(self):self.size = 10 ** 9self.segTree = MySegment(size = self.size)def book(self, start: int,end: int) -> bool:if(self.segTree.query(self.segTree.node,0,self.size,start,end-1) != 0):return Falseelse:self.segTree.update(self.segTree.node,0,self.size,start,end-1,1)return True# Your MyCalendar object will be instantiated and called as such:
# obj = MyCalendar()
# param_1 = obj.book(start,end)

二、补充说明

  不想在线段树的的具体结构上进行详细叙说,可以直接看一下黄浩杰大神的视频讲解,直观地理解线段树是什么?编写的思路。而后根据上述的python代码进行理解,其实写到后面我感觉这就是一堆公式啊!挺无语的,不过这效率委实不高。

三、总结

  本篇blog主要是对python线段树的编写的一个model,因为网上大部分都是java、C语言的,有关python的太少了,几乎没有!其实没有也是有道理的,线段树用python编写太慢了,不过学习一下总是没有坏处的。我看到LC上线段树的五六道题都可以用二分法进行快速简便求解,下面将会针对python的二分函数进行一个汇总。

python线段树编写,很冗长,不过不难理解。相关推荐

  1. 线段树 by yyb

    线段树 by yyb Type1 维护特殊信息 1.[洛谷1438]无聊的数列 维护一个数列,两种操作 1.给一段区间加上一个等差数列 2.单点询问值 维护等差数列 不难发现,等差数列可以写成\(ad ...

  2. 线段树/树状数组问题 | 问题集合

    写在前面 线段树代码实在冗长,于是乎能用树状数组直接搞的就懒得打线段树了(:溜 1.P2620[QZYZ] 校门外的树 描述 Description 校门外有很多树,有苹果树,香蕉树,有会扔石头的,有 ...

  3. 线段树模板hdu 1754:I Hate It

    I Hate It Time Limit: 9000/3000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total ...

  4. P5305-[GXOI/GZOI2019]旧词【树链剖分,线段树】

    正题 题目链接:https://www.luogu.com.cn/problem/P5305 题目大意 给一棵有根树和kkk,QQQ次询问给出x,yx,yx,y求 ∑i=1xdepLCA(i,y)k\ ...

  5. poj 2528 Mayor's posters(线段树+离散化)

    1 /* 2 poj 2528 Mayor's posters 3 线段树 + 离散化 4 5 离散化的理解: 6 给你一系列的正整数, 例如 1, 4 , 100, 1000000000, 如果利用 ...

  6. 【AC军团周报(第一周)第一篇】线段树从入门到入土【1】

    本文章连载AC军团周报 -> 线段树 : 从入门到入土[1] 前言: 正如你所见,我这系列文章可以从入门来看,想入土的(伪)也可以进行观看(逃 本系列的文章将详讲线段树的思想,代码实现,并以一部 ...

  7. Luogu P3373 【模板】线段树 2

    这还是比较简单的线段树模板题吧 更多的是给一个思路,当维护多种需要Lazy Tag的操作时顺序问题 这里的话加法和查询都可以参照区间加法模板题和Sol 主要是当标记下传的时候,要注意先处理乘法在处理加 ...

  8. 【数据结构】线段树的扩展与应用

    线段树是一种非常基础的数据结构,但有的时候仅仅是普通的线段树无法满足需求,那么我们就要对其进行一些扩展. Chapter1:标记永久化 实现 普通的线段树通过懒标记(Lazy Tag)以 O ( n ...

  9. 线段树合并(四道例题)

    顾名思义,就是合并两个同构(就是维护的区间长度一样)线段树,其实也没啥比较nb的算法,就是一个一个节点的合并,但是如果在n个要合并的线段树里,如果一共有m个元素,则配合动态开点,复杂度会均摊成一个惊人 ...

最新文章

  1. 【Java】排序算法之 冒泡排序
  2. 关联查询取更新时间_数据分析之sql复杂查询
  3. WinAPI: waveInGetNumDevs - 获取波形输入设备的数目
  4. [轉]SQL Server 2005备份维护计划
  5. git checkout -b dev origin/dev详解
  6. JasperReports是一个开源的java报表制作引擎
  7. 学习Python的几个必要条件,你具备吗?
  8. java音乐登陆界面_第四篇——Spring音乐登录界面设计及实现(C#)
  9. Openfire on Centos7
  10. Array对象的三种属性实例
  11. TortoiseGit和msysGit安装及使用笔记(windows下使用上传数据到GitHub)[转]
  12. 拓端tecdat|R语言用泊松Poisson回归、GAM样条曲线模型预测骑自行车者的数量
  13. ANC主动降噪技术的原理
  14. NPOI Word 原有表格增加一行
  15. android 如何定位anr,ANR产生的原因及其定位分析
  16. 高斯混合模型的终极理解
  17. Nordic Thingy:52 Android App 源码及APK
  18. 有小伙伴说看不懂 LiveData、Flow、Channel,跟我走
  19. .tga图片的文件格式分析
  20. python建立复数数组_深入理解NumPy简明教程---数组1

热门文章

  1. jquery html隐藏标签,js(jQuery)控制html元素隐藏
  2. linux运行文件命令
  3. 企业线上活动如何做虚拟直播?如何搭建3D虚拟场景直播间?
  4. iloc函数使用方法
  5. 手机位置服务寻求新突破 推出英文系统把握奥运契机
  6. HEVC,VP9,x264性能对比
  7. RabbitMQ fanout广播模式
  8. 亲,这边建议您的vs2017写代码背景图换个萌妹子呢~
  9. 网页html中嵌入特殊字体-此法利于SEO
  10. Arcgis去除黑色背景值的有效方法!!!