【题解】「LibreOJ NOI Round #2」小球进洞

题目链接

题目大意

有若干个小球放在数轴上,第 \(i\) 号小球的坐标参数为 \(a_i\)

有两种操作:

  1. 输入 \(i,v\),修改第 \(i\) 号小球的坐标参数为 \(a_i\gets v\)

  2. 输入 \(l,r\),询问下述内容:

    按照 \(a_i\) 从小到大的顺序(\(a_i\) 相等时按 \(i\) 从小到大的顺序)依次将小球放在数轴上。第 \(i\) 号小球放在 \(\le a_i\) 的没有被之前放置的小球占据的最大的整点处,设第 \(i\) 号小球放置的位置为 \(b_i\)

    请你输出 \(\sum_{i=1,2,\dots , n,[l,r]\subseteq [b_i,a_i]} (a_i+b_i)\) 的值。也即,所有满足 \(b_i\le l,a_i\ge r\) 的小球的 \(a_i+b_i\) 之和。

题解

LCT是不可能LCT的,这辈子都不可能LCT的。

官方题解有两篇,一篇LCT,一篇【待填】,只好阅读理解

首先, \(b_i\) 就是 \(a_i\) 前面第一个满足与 \(a_i\) 之间的小球个数不超过距离的位置。

\(cnt_i=\sum_j[a_j=i],c_i=c_{i-1}+1-cnt_i,val_{i.l}=\sum_j[a_j=i,b_j\leqslant l]\) ,则:

\[\Large val_{i,l}=\begin{cases} cnt_i(i\leqslant l)\\ \max(\min_{l\leqslant j<i}c_j-c_i,0)(i>l) \end{cases} \]

感性证明:当 \(i\leqslant l\) 时,显然;当 \(i>l\) 时,当讨论了 \(a_j=l\) 后,在 \([1,l]\) 的空位只剩下 \(c_j\) 个,且不会增加。当讨论了 \(a_j=k\) 后,在 \([1,l]\) 的空位只剩下不超过 \(c_k\) 个。所以,当讨论到 \(a_j=i\) 时,在 \([1,l]\) 的空位只剩下 \(\min_{l\leqslant j<i}c_j\) 个,讨论后还剩 \(\min_{l\leqslant j\leqslant i}c_j\) 个, \(val_{i,l}\) 即为两者之差。

所以,可以将答案式子给拆成 \(a,b\) 两部分,考虑分别算。

先考虑如何由上面的式子推 \(\sum a_i\)

容易发现, \(\sum a=\sum_{i\geqslant r}i\cdot val_{i,l}\) ,所以可以从前往后扫一遍,每次遇到一个更小的 \(c_i\) 就统计答案,再取 \(\min\)

如何做到更优秀的复杂度呢?可以考虑线段树。对于每个节点,考虑记录:当左侧的最小值等于左儿子的最小值时,右儿子对答案的贡献 \(suma\) 。这个在预处理时可以递归解决。在算答案时,若左侧的最小值大于左儿子的最小值时,只用递归左儿子,再加上 \(suma\) ,否则左儿子的贡献为 \(0\) ,直接递归右儿子。

然后就是推 \(\sum b_i\)

\(sum_{l,r}\) 表示当前考虑了值在 \([n+1,r]\) 中的所有 \(a_i\) ,在 \(\{b\}\) 中没出现过且 \(\leqslant l\) 的正整数之和。

\(\sum b_i=sum_{l,2n}-sum_{l,r-1}\)

\(\{b\}_r\) 表示讨论完 \(a_i\leqslant r\) 时的 \(b\) 集合。

类似的,设 \(val'_{i,r}=[i\notin \{b\}_r]\) ,则 \(sum_l=\sum_{i\leqslant l}i\cdot val'_i\) 。可以得到:

\[\Large val'_{i+1,r}=[\min_{i<j\leqslant r}c_j>c_i] \]

就可以用类似于求 \(\sum a\) 的方法来求了。

修改时就先删除再重新插入。复杂度 \(\Theta((n+q)\log^2 n)\)

注意判 \(l=r\) 的情况。

posted @ 2020-06-30 09:30  ztc…  阅读(601)  评论(0编辑  收藏  举报

Please contact lydsy2012@163.com!