来解释一下许多细节和疑问
在简化问题考虑左下中,为什么按照横坐标从小到大排序就好了?不应该还要以纵坐标为第二关键字排序吗?不然有可能某次询问的下面一个点()还没有更新就轮到了,这就无法统计了啊?
答:如果单独考虑左下的话,这个做法确实有问题,也的确需要以纵坐标为第二关键字排序。但是如果考虑四个方向的话,只以横坐标排序就是没问题的,上面说的这种情况会在其他时候被统计到。比如就说上面说的这种情况,那么当这种情况出现的时候,我们左下的确是无法统计的,但是轮到统计右下的时候,我们此时(相对于左下)是倒着循环的,之前在左下没有被先添加进去的说明他在序列中的位置在之后,所以此时就一定会被先添加,然后就会被统计了
为什么可以用树状数组统计没有可加性的最大值?
答:我们考虑一下为什么树状数组不能统计最大值。翻到蓝书的P203,看看那个树状数组的图,想一下如果我们没有修改操作而是只有初始的序列,那么我们如何更新树状数组?答案当然就是对每一个树状数组,对他的所有儿子取最大值(比如),没有修改操作的情况下,这个显然是对的(维护的就是的最大值)。那我们现在加入修改操作。如果我们将修改为,用最暴力的方法,如果更新数组?这里不太好用文字说明,我先举一个例子。比如修改,那我们先找到,令,然后再找到,令。所以就是找到对应位置的树状数组,然后一路往上,对经过的每一个节点,都要重新对其所有儿子取最大值。之所以要这么做,是因为有可能会出现一种情况,比如刚好等于,而恰好又是的严格最大值,而我们修改的刚好严格小于,这下就没办法直接说明最新的最小值了,所以我们必须比较暴力的更新。然而对于一般的问题来说,即使我们暴力更新了,我们也没办法查询的最大值,因为最大值是没有可加性的。但是回到这一道题目,可以证明,四个方向都不会出现上述说明的情况,比如统计左下方的时候,扫描到一个点,由于我们按照了从小到大排序,此时修改序列的,一定能被修改成功(也就是上文说的一定大于),于是就不会出现上文说的情况,所以就可以像代码一样区间更新。而这道题目刚好又是只用查询的最大值,所以即使不满足可加性问题也不大
为什么统计左上的时候修改的位置要变为?
答:就像上文提到的,这里之所以能用树状数组是因为我们不用满足可加性,查询的是,这里为了继续利用这个性质,由于我们此时要查询的是,所以我们要把他倒过来统计
最后提一嘴时间复杂度的计算,一共有层,每层的总时间复杂度,所以时间复杂度为
代码就看打卡代码,写的很好,学习简化代码的技巧
另外这道题目可以转化成三维偏序问题,加入时间维即可,也就是二维偏序+动态修改
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构