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

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. AtCoder ABC 129E Sum Equals Xor

    题目链接:https://atcoder.jp/contests/abc129/tasks/abc129_e 题目大意 给定一个二进制表示的数 L,问有多少对自然数 (a, b) 满足 $a + b ...

  2. QT之QComboBox

    1.addItems需要注意的事项: 1.在QT中设置maxVisibleItems的值,设置Items的最大可显示的值.(一般默认为10) 2.在每次需要清除已经添加的tems的时候需要注意,ui. ...

  3. 19.SimLogin_case06

    # 使用自造的cookies登录GitHub import requests from lxml import etree str = '_octo=GH1.1.518803230.153726461 ...

  4. 面试系列12 redis和memcached有什么区别

    (1)redis和memcached有啥区别 这个事儿吧,你可以比较出N多个区别来,但是我还是采取redis作者给出的几个比较吧 1)Redis支持服务器端的数据操作:Redis相比Memcached ...

  5. 《代码整洁之道》ch5~ch9读书笔记 PB16110698(~3.15) 第二周

    <代码整洁之道>ch5~ch9读书笔记 本周我阅读了本书的第5~9章节,进一步了解整洁代码需要注意的几个方面:格式.对象与数据结构.错误处理.边界测试.单元测试和类的规范.以下我将分别记录 ...

  6. 一个简单的SpringBoot入门程序

    1. 使用IDEA构建Maven项目 <?xml version="1.0" encoding="UTF-8"?> <project xmln ...

  7. vue-draggable-resizable 拖拽缩放插件

    安装: npm install --save vue-draggable-resizable 使用: <template>   <div style="height: 50 ...

  8. csps-s模拟测试62,63Graph,Permutation,Tree,Game题解

    题面:https://www.cnblogs.com/Juve/articles/11631298.html permutation: 参考:https://www.cnblogs.com/clno1 ...

  9. csp-s模拟测试55 联,赛,题题解

    题面:https://www.cnblogs.com/Juve/articles/11610969.html 联: 用线段树维护区间和,要修改成1或0就线段树修改区间和 如果是异或,那么新的区间和就是 ...

  10. 07.27NOIP模拟赛

    戳这里下载过去三次NOIP模拟赛总成绩 (别嘲笑垫底的我...解压密码为信奥生所在的两个班的班号,文档密码为机房开机用户名+密码) 又一次垫底…… 我难受. 上来感觉T1不可做,T2和蔼可亲,T3一脸 ...