线段树实现。很多细节值得品味 都在注释里面了

class SegTree:
def __init__(self,N,query_fn,update_fn):
self.tree=[0]*(2*N+2) # 最后一个节点有可能无用 ,但是确保树是完全的
self.lazy=[0]*(N+1)
self.N=N self.h=0
while ((1<<self.h) < N ):
self.h=self.h+1 self.query_fn=query_fn
self.update_fn=update_fn #这里实现只有单个节点的更改,对于整个节点来说以上的节点没有杯更新到 所以要使用 pull 做进一步的更改
def _apply(self,x,val):
self.tree[x] = self.update_fn(val,self.tree[x]) if(x<self.N):
self.lazy[x]=self.update_fn(self.lazy[x] , self.tree[x]) '''
pull
从叶部到根部 ,用于更新后的维护 push
从根部到叶部 ,查询前的维护 ''' def pull(self,x): while x>1 : # 先while 再除 保证了 (x==1 仍然会执行&&第一次执行的时候不是叶子节点)
x = x // 2
self.tree[x] = self.query_fn(self.tree[x*2+1],self.tree[x*2 ] ) #针对区间之间的信息 是 query_fn self.tree[x] = self.update_fn(self.tree[x],self.lazy[x]) def push(self,x):
for i in range(self.h,0,-1):
y = x >> i
if(self.lazy[ y ]): #巧妙的使用了 lazy 前空出无用的 lazy[0]
self._apply(y*2, self.lazy[y]) #_apply 代码的复用 (修改值 并且置 lazy )
self._apply(y*2+1, self.lazy[y])
self.lazy[y]=0 def update(self,left,right,val):
#print("update "+str(left )+" "+str(right )+" "+str(val))
left =left +self.N
right=right+self.N init_left = left
init_right = right
while(left<=right): #追溯最邻近父节点的写法 if( left & 1 ):
self._apply(left , val )
left = left +1 if((right & 1) ==0):
self._apply(right, val)
right = right -1 left = left // 2
right = right // 2 #以上只更新到左右节点的最邻近父节点 所以需要进行pull 更新上面的所有节点
self.pull( init_left )
self.pull( init_right ) def query(self,left,right):
#print("query "+str(left )+" "+str(right ))
left = left +self.N
right = right + self.N
self.push( left )
self.push( right ) ans = 0
while ( left <= right ):#追溯最邻近父节点
#print("left "+str(left)+" right"+str(right))
if(left & 1): ans= self.query_fn(ans , self.tree[left] )
left = left + 1 #这个+1 是为了对称 没有实际意义? if((right & 1) ==0 ):
#print(right)
ans = self.query_fn(ans , self.tree[right ])
right = right -1 left = left // 2
right = right // 2
return ans class Solution:
def fallingSquares(self, positions):
"""
:type positions: List[List[int]]
:rtype: List[int]
"""
position = [i[0] for i in positions]
position . extend([i[0]+i[1]-1 for i in positions]) position=sorted(set(position)) pos2idx ={pos:i+1 for i,pos in enumerate(position)} N=len(pos2idx) #print("N is "+str(N))
segtree=SegTree(N,max,max) best = -1
ans_list = []
#print(pos2idx)
for block in positions:
l,r=pos2idx[block[0]],pos2idx[block[0]+block[1]-1] height = segtree.query(l,r) + block[1]
#print("query height"+str(height-block[1])+" blcok size:"+str(block[1])) segtree.update(l,r,height) best=max(best,height) ans_list.append(best) return ans_list

leetcode 699. Falling Squares 线段树的实现的更多相关文章

  1. 【leetcode】699. Falling Squares

    题目如下: On an infinite number line (x-axis), we drop given squares in the order they are given. The i- ...

  2. 699. Falling Squares

    On an infinite number line (x-axis), we drop given squares in the order they are given. The i-th squ ...

  3. 【LeetCode】线段树 segment-tree(共9题)+ 树状数组 binary-indexed-tree(共5题)

    第一部分---线段树:https://leetcode.com/tag/segment-tree/ [218]The Skyline Problem [307]Range Sum Query - Mu ...

  4. HDU 1264 Counting Squares (线段树-扫描线-矩形面积并)

    版权声明:欢迎关注我的博客.本文为博主[炒饭君]原创文章,未经博主同意不得转载 https://blog.csdn.net/a1061747415/article/details/25471349 P ...

  5. C#LeetCode刷题-线段树

    线段树篇 # 题名 刷题 通过率 难度 218 天际线问题   32.7% 困难 307 区域和检索 - 数组可修改   42.3% 中等 315 计算右侧小于当前元素的个数   31.9% 困难 4 ...

  6. Sum of Squares of the Occurrence Counts解题报告(后缀自动机+LinkCutTree+线段树思想)

    题目描述 给定字符串\(S(|S|\le10^5)\),对其每个前缀求出如下的统计量: 对该字符串中的所有子串,统计其出现的次数,求其平方和. Sample Input: aaa Sample Out ...

  7. 【Codeforces720D】Slalom 线段树 + 扫描线 (优化DP)

    D. Slalom time limit per test:2 seconds memory limit per test:256 megabytes input:standard input out ...

  8. poj 1195:Mobile phones(二维线段树,矩阵求和)

    Mobile phones Time Limit: 5000MS   Memory Limit: 65536K Total Submissions: 14391   Accepted: 6685 De ...

  9. Codeforces Round #337 (Div. 2) D. Vika and Segments 线段树 矩阵面积并

    D. Vika and Segments     Vika has an infinite sheet of squared paper. Initially all squares are whit ...

随机推荐

  1. <每日一题>算法题:集合求并集并排序

    题目描述 给你两个集合,要求{A} + {B}. 注:同一个集合中不会有两个相同的元素. 输入描述: 每组输入数据分为三行,第一行有两个数字n,m(0 ≤ n,m ≤ 10000),分别表示集合A和集 ...

  2. neo4j安装APOC插件

    1.APOC下载地址:https://github.com/neo4j-contrib/neo4j-apoc-procedures/releases/3.4.0.1 只要下载.jar这一个压缩文件就好 ...

  3. Eclipse 连接MySql数据库总结

    Eclipse 连接MySql数据库总结 一.在MySql中创建数据库,并创建表,向表中插入数据 1.创建数据库 create database select_test 2.创建表 create ta ...

  4. sparkStreaming结合sparkSql进行日志分析

    package testimport java.util.Propertiesimport org.apache.spark.SparkConfimport org.apache.spark.Spar ...

  5. iOS开发系列-线程状态

    概述 线程从创建到销毁中间存在很多种状态. 线程的状态 通过NSThread创建一条线程,开发者需要负责线程的创建和执行,线程的销毁由系统决定.创建一个继承NSThread的FMThread类,重写d ...

  6. linux普通用户无法登录mysql

    一.前言 本帖方法只适用于普通用户无法登录,但root用户可以登录的情况. 今天将war包放入linux后,运行报错,经过检查发现是数据库连接不上.奇怪的是,用户名和密码都是正确的,所以有了以下发现. ...

  7. selenium学习笔记——driver.get(url) 页面加载时间太长

    # 两个同时设置才行 # 实现效果:加载状态停止,进行代码下一步操作 driver.set_page_load_timeout(10) driver.set_script_timeout(10) # ...

  8. Mr. Young's Picture Permutations

    Mr. Young's Picture Permutations 给出一个有k列的网格图,以及每列图形的高度\(n_i\),下端对齐,保证高度递减,设有n个网格,询问向其中填1~n保证每行每列单调递增 ...

  9. leetcode-142-环形链表②

    题目描述: 方法一:O(n) O(n) # Definition for singly-linked list. # class ListNode(object): # def __init__(se ...

  10. 聊聊MVC和模块化以及MVVM和组件化

    原文链接 小寒的博客,带你理解更深的世界 面向对象,模块化和MVC 面向对象是指把写程序映射到现实生活,从而一来逻辑性更强,更容易写好代码,二来代码很贴切,通俗易懂,更被人理解,三来更加容易拓展和管理 ...