影魔

这一道题目有一个非常重要的思想,就是确定一个基准

就像计数题目一样,我们将一个区间确定一个基准,我们一般用端点作为基准,然而这道题目却行不通

但是这道题目的题干却一直提到最大值,所以我们以一个区间的最大值为基准,显然可以唯一确定

那么就不难确定一个区间[a,b],以(a,b)的最大值为基准

所以我们对每一个数,求出它左边和右边距离他最近的又比他大的数(单调栈)

然后按照题解处理即可(看到无修改,可以想到离线)

解释一下他这个处理方法,考虑[l,r]这个区间所有点的贡献所包含的类型只有题解中说到的三种类型。对于题解中提到的sum2,包含所有三种类型的和,然而此时有些第三种类型产生的贡献我们是不想要的(左端点小于l),于是我们只用在进入l之前统计一下这些端点所产生的贡献就好了(这个思想跟“校门外的树”一样)

也可以用类似于HH的项链的方法,我们的代码用的是这个方法

这两种方法都要记下来,我们对第二种方法更加熟悉,然而第一种方法也是有应用的,比如在某些子树的统计题目里面:进入子树之前记录数组值,递归完之后准备出去的时候再记录数组值,相减即得答案

update 2024.5.16

我们也可以以区间的端点作为基准,下面以第一类贡献为例讨论

我们仍然像上面这样处理处LR数组,然后从左往右扫描,当我们扫描到r这个点的时候,有可能产生贡献的区间左端点的范围就是[rL[r],r1],我们只用再在这些点中统计出有多少点i满足i+R[i]r即可

如果我们已经维护好了一个序列,若第i个位置的值为,那么直接用树状数组查询前缀和就好了;在我们从r变成r+1的时候,我们只用把所有满足i+R[i]=r的位置的值变为0就好了,并且将[r+1,r+1+R[r+1]1]的位置全部变1,也可以用树状数组做到

还有一个问题,就是这道题目的询问是某一个区间,此时就要像题解那样子处理:对于一个区间[l,r],在扫描到l1的时候统计此时区间[l,r]的总和,之后减掉就好了

以上做法有问题,可以想一下应该怎么做

posted @   最爱丁珰  阅读(8)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
点击右上角即可分享
微信分享提示