[Ynoi2019] 魔法少女网站

  • 题意

    给定一个长为 n 的序列 {a} ,支持:

    1. 单点修改。
    2. 查询区间 [l,r] 最大值小于等于 x 的子区间个数。

    n,m3×105,ai[1,n]

    3.5s,64MB​

  • 题解

    容易发现,对于查询操作,我们如果把 x 的数设为 1 ,其余为 0 ,那么一个长为 len 的极长 1 连续段的贡献为 len(len+1)2

    那么暴力即为从左到右模拟整个过程,维护后缀 1 连续段的长度。

    考虑优化这个模拟过程,不难想到序列分块。

    设块长为 B ,那么一个块内本质不同的答案只有 O(B) 个。

    对于查询区间 [l,r] ,边角暴力。对于中间的块,我们需要维护 x1 连续段前缀长度,后缀长度,以及除去前后缀的块内贡献。

    如果我们对每个块,从小到大处理每个元素,利用链表或并查集等维护 1 连续段,能做到一次 O(B) 求出一个块所有本质不同的答案。

    那么我们预处理直接对块内排序,修改就类似插入排序的方式维护排序后的数组,块内信息暴力重构,那么预处理复杂度是 O(nlogn) ,修改一次复杂度是 O(B)

    询问对于一个块我们还需要找到 x 的位置,复杂度一次是 O(B+nBlogB)

    不难得出 B=nlogn 最优,总复杂度 O(nlogn+mnlogn)

    然而这大概率不能通过这道题,我们继续优化。

    注意到瓶颈在于找到 x 在一个块内的位置,这是一个前缀和问题,我们有 O(n)O(1) 的值域分块,而空间限制导致我们不能对每个块开一个前缀和数组,那么容易想到离线,逐块处理,每次利用 O(n)O(1) 的值域分块做到 O(1) 查询位置。

    我们来分析复杂度。

    预处理不变: O(nlogn)

    多了新操作每个块的处理: O(n2B)

    修改要增加一个值域分块: O(m(B+n))

    查询把 logB 去掉: O(m(B+nB))

    那么 B=n 最优,总复杂度 O((n+m)n)

posted @   leukocyte  阅读(423)  评论(0编辑  收藏  举报
编辑推荐:
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
点击右上角即可分享
微信分享提示