leetcode 699. Falling Squares 线段树的实现
线段树实现。很多细节值得品味 都在注释里面了
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 线段树的实现的更多相关文章
- 【leetcode】699. Falling Squares
题目如下: On an infinite number line (x-axis), we drop given squares in the order they are given. The i- ...
- 699. Falling Squares
On an infinite number line (x-axis), we drop given squares in the order they are given. The i-th squ ...
- 【LeetCode】线段树 segment-tree(共9题)+ 树状数组 binary-indexed-tree(共5题)
第一部分---线段树:https://leetcode.com/tag/segment-tree/ [218]The Skyline Problem [307]Range Sum Query - Mu ...
- HDU 1264 Counting Squares (线段树-扫描线-矩形面积并)
版权声明:欢迎关注我的博客.本文为博主[炒饭君]原创文章,未经博主同意不得转载 https://blog.csdn.net/a1061747415/article/details/25471349 P ...
- C#LeetCode刷题-线段树
线段树篇 # 题名 刷题 通过率 难度 218 天际线问题 32.7% 困难 307 区域和检索 - 数组可修改 42.3% 中等 315 计算右侧小于当前元素的个数 31.9% 困难 4 ...
- Sum of Squares of the Occurrence Counts解题报告(后缀自动机+LinkCutTree+线段树思想)
题目描述 给定字符串\(S(|S|\le10^5)\),对其每个前缀求出如下的统计量: 对该字符串中的所有子串,统计其出现的次数,求其平方和. Sample Input: aaa Sample Out ...
- 【Codeforces720D】Slalom 线段树 + 扫描线 (优化DP)
D. Slalom time limit per test:2 seconds memory limit per test:256 megabytes input:standard input out ...
- poj 1195:Mobile phones(二维线段树,矩阵求和)
Mobile phones Time Limit: 5000MS Memory Limit: 65536K Total Submissions: 14391 Accepted: 6685 De ...
- 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 ...
随机推荐
- python元组与字典
一.元组 1.元组的表达 (1,2,3,4) ('olive',123) ("python",) 创建元组: a=tuple((1,2,3,)) b=("python&q ...
- [课后作业] 第002讲:用Python设计第一个游戏 | 课后测试题
试题: 0. 什么是BIF? 1. 用课堂上小甲鱼教的方法数一数 Python3 提供了多少个 BIF? 2. 在 Python 看来:'FishC' 和 'fishc' 一样吗? 3. 在小甲鱼看来 ...
- oracle 如何在一个数据库创建多个实例
实例:是一个非固定的.基于内存的基本进程与内存结构.当服务器关闭后,实例也就不存在了. 数据库(Database)指的是固定的.基于磁盘的数据文件.控制文件.日志文件.参数文件和归档日志文件等. 一般 ...
- swagger请求参数在header中添加token
网友大部分说的是如下配置 参照配置然而没有作用 注掉改红框内的配置,在方法上加如下注释就可以用 @ApiImplicitParams({ @ApiImplicitParam(paramType = & ...
- Easy Excel导出
@GetMapping(value = "/down2") public void down2(HttpServletResponse response) throws Excep ...
- Python全栈开发:初识Python
Pythton简介 python的创始人为吉多·范罗苏姆(Guido van Rossum).1989年的圣诞节期间,吉多·范罗苏姆为了在阿姆斯特丹打发时间,决心开发一个新的脚本解释程序,作为ABC语 ...
- AutoIt自动化编程(4)【转】
五.自动化操作轻松入门系列5 控件操作 然而,在真正实现自动化时仅靠上面的技术往往难以达到预期目的.下面开始进入最为重要的控件操作. 1.设置文本 在安装软件的过程中用户往往需要提供一些必需信息,比如 ...
- 使用JS实现页面中动态添加文件上传输入项
1. 编写JSP <%@ page language="java" import="java.util.*" pageEncoding="UTF ...
- 廖雪峰Java13网络编程-3其他-1HTTP编程
1.HTTP协议: Hyper Text Transfer Protocol:超文本传输协议 基于TCP协议之上的请求/响应协议 目前使用最广泛的高级协议 * 使用浏览器浏览网页和服务器交互使用的就是 ...
- day07 linux磁盘分区,ps,kill,df,top命令使用
day07进入单用户模式删除密码不能进入系统问题: SELINUX=disabled 操作系统linux开机流程加电BIOS找到启动介质先读取第一个扇区(MBR)grup找到kernel加载到内存执行 ...