【题解】[COCI2020-2021#5] Sjeckanje
solution:
数据结构毒瘤题。
算法一:考虑不带修改。首先分析出一个性质,最优区间一定是单调区间。因为 f ( l , r ) ≤ m a x ( l , r ) − m i n ( l , r ) f(l,r)\leq max(l,r)-min(l,r) f(l,r)≤max(l,r)−min(l,r) ,如果一个区间不是单调区间的话可以继续拆分直到都是单调区间,从而使得 f ( l , r ) ≥ m a x ( l , r ) − m i n ( l , r ) f(l,r)\geq max(l,r)-min(l,r) f(l,r)≥max(l,r)−min(l,r) 。设 f [ i ] f[i] f[i] 表示前 i i i 个数贡献的最大值,可以 O ( n ) O(n) O(n) 求出,区间 ( l , r ] (l,r] (l,r] 的贡献就是 a [ r ] − a [ l + 1 ] a[r]-a[l+1] a[r]−a[l+1] 。加上修改的话就暴力修改,时间复杂度 O ( n 2 ) O(n^2) O(n2) 。
算法二:考虑维护差分数组,将区间修改转化为单点修改。现在对于单调区间 [ l , r ] [l,r] [l,r] ,其贡献等于 ∑ i = l r c [ i ] \sum_{i=l}^rc[i] ∑i=lrc[i] 。进一步地,总贡献等于 ∑ i = 1 n c [ i ] \sum_{i=1}^nc[i] ∑i=1nc[i] ,所以我们只需要维护差分数组的和即可。规定 c [ 1 ] = 0 c[1]=0 c[1]=0 。当然实际计算是求的绝对值的和。
一个坑点在于, l e n = 1 len=1 len=1 的情况是没有贡献的,比较难判断。所以我们必须调整我们的策略:转化为在差分序列中选择一些数,使得选择的数中不存在相邻两个数,一个为正,一个为负。证明也比较容易,考虑 c [ i ] c[i] c[i] 能产生贡献当且仅当 [ i , i + 1 ] [i,i+1] [i,i+1] 在同一区间,如果有两个相邻的线段不能在同一集合的话就不能都产生贡献,反之则能。
现在我们可以用线段树维护了。 d p [ t ] [ 0 / 1 ] [ 0 / 1 ] dp[t][0/1][0/1] dp[t][0/1][0/1] 表示节点 t t t 的 左/右 端点 不选/选 时贡献的最大值。时间复杂度 O ( 2 4 ( n + q ) l o g n ) O(2^4(n+q)logn) O(24(n+q)logn) 。
__EOF__

本文链接:https://www.cnblogs.com/cqbzly/p/17530289.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角【推荐】一下。您的鼓励是博主的最大动力!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· DeepSeek 开源周回顾「GitHub 热点速览」