淄博市网站建设_网站建设公司_论坛网站_seo优化
2025/12/30 21:42:45 网站建设 项目流程

洛谷 P5047

\(n, m\) 同阶。

题目中提到了 \(n^{1.5}\) 这个复杂度,虽然有神秘的 \(n^{\sqrt 2}\) 做法,但是 \(n\sqrt n\) 也足以通过(即使只有 \(250ms\)

考虑有什么根号算法?那就莫队吧。(其实莫队属于一种分块)

考虑从 \([l, r - 1]\) 挪动到 \([l, r]\),其实变化量就是 \(a_{l \sim r - 1}\) 中大于 \(a_r\) 的数量,用树状数组可以随便搞出 \(O(n \sqrt n \log n)\) 的做法,和暴力一样

如何优化呢?注意到这个是可以差分的,所以考虑二次离线莫队。令 \(f(x, l, r)\) 表示 \(a_{l \sim r}\) 中大于 \(a_r\) 的数量,那么 \(f(x, l, r) = f(x, 1, r) - f(x, l - 1)\)。令 \(F(x, r) = f(1, l, r)\),那么变化量就是 \(f(r, l, r - 1) = F(r, r - 1) - F(r, l - 1)\)

\(F(r, r - 1)\) 是好算的,主要是 \(F(r, l - 1)\)。根据二次离线的套路,考虑扫描线。从 \(1\) 扫到 \(l - 1\),维护每个 \(r\) 的答案。

问题转化为了 \(O(n)\) 次区间加,\(O(n \sqrt n)\) 单点查。为了平衡复杂度,需要使用值域分块(树状数组两种都是 \(O(\log n)\))。即对 \(O(\frac{n}{B})\)整块的整块打上标记,散块暴力加,查询时把两种标记加起来即可。这样就可以做到修改 \(O(\sqrt n)\),查询 \(O(1)\)

为了把查询的 \(r\) 存下来,可以发现 \(r\) 其实是一端区间,直接开个 vector 记录区间做右端点即可,这样将空间降为 \(O(n)\)

\(F(r, r - 1)\) 也是可以一并算的。对于左端点移动将 \(f\) 中的“大于”换为“小于”即可。

时间复杂度:\(O(n \sqrt n)\)

总结:想要搞出一个 \(O(n \log n)\) 的做法比较困难,结合题目提示可以想到莫队。不难搞出一个带 \(\log\) 做法,通过二次离线配合值域分块去掉 \(\log\)

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询