【题解】「LibreOJ NOI Round #2」小球进洞
题目大意
有若干个小球放在数轴上,第 \(i\) 号小球的坐标参数为 \(a_i\)。
有两种操作:
-
输入 \(i,v\),修改第 \(i\) 号小球的坐标参数为 \(a_i\gets v\);
-
输入 \(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]\) ,则:
感性证明:当 \(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\) 。可以得到:
就可以用类似于求 \(\sum a\) 的方法来求了。
修改时就先删除再重新插入。复杂度 \(\Theta((n+q)\log^2 n)\) 。
注意判 \(l=r\) 的情况。