前言:
记录2月一些好题的解法,同时有可能会补以前写过的题目。
CF718C Sasha and Array
对于每一个下标 \(i\) 记数对 \(S_i=(a_i, b_i)\)。代表第 \(i\) 个位置斐波那契数列的前第 \(0\) 项和第 \(1\) 项是 \(a_i\) 和 \(b_i\)。例原数组中 \(a[3]=3\),则 \(S_{3}=(1, 2)\)。考虑对 \(a_i\) 加 \(x\),\(S_i\) 变成了原本的 \(a_i\) 和 \(b_i\) 向后推了 \(x\) 项后组成的新数对。
继续考虑区间的查询和更新。我们用线段树维护。对于区间 \([l, r]\)。在线段树上维护\(\displaystyle S_{[l,r]}=(\sum_{i=l}^{r}a_i,\sum_{i=l}^{r}b_i)\)。统计区间 \([l, r]\) 的时候返回 \(b_{[l, r]}\)。修改时,有性质,若有若干个满足 \(a_{i}=a_{i-1}+a_{i-2}\) 数列,则数列 \(f\) 满足 \(\displaystyle f_{i}=\sum a_{i}\),则 \(f\) 同样满足 \(f_{i}=f_{i-1}+f_{i-2}\)。所以更新时直接将 \(S_{[l, r]}\) 按斐波那契的规律向后推即可。
P3616 富金森林公园
洛谷的题解中给出了一些根据高度凹凸来讨论答案变化的做法,但讨论较为复杂,而且细节较多。这里给出一种较为清晰的解法。将露出水面的相邻山峰进行连边。易得,在任一水面的情况下,答案为露出山峰所构成的连通块的数量。而联通块的数量不好直接表示,转化为露出水面的山峰数减去露出水面的边数(即边连接的两山峰均在水面上的边),因为在任意两座露出的山峰间建边,都会使连通块的数量少 \(1\)。先将初始情况时,不同水面时的答案预处理出来,放进一个数组里,即 \(ans[i]\) 表示水面高度为i时的答案。考虑更新一座山峰,\(ans\) 数组会如何变化,发现需要区间修改。使用线段树维护即可。
CF474F Ant colony
区间不符合要求的数难以统计,可以转换成区间长度减去区间符合要求的数。区间中符合要求的数,一定是区间所有数的 \(gcd\)。在线段树上记录区间最小值及其出现次数和区间 \(gcd\)。若区间最小值等于区间 \(gcd\),则符合要求的数既是区间最小值的出现次数;否则区间里没有符合要求的数。
CF803G Periodic RMQ Problem
维护动态开点线段树,不建出真实的树,只有在更新和查询需要时新建节点。可以发现,在新建节点时,此节点的区间之前没有被更新过,我们需要给其初始状态,故使用st表实现 \([1, n]\) 内最小值的 \(O(1)\) 查询。
CF718C Sasha and Array
线段树维护区间和和区间加标记。这题主要困难在区间标记的下传。可以参考CF718C Sasha and Array的做法,维护起始的数对作为标记,更新时使用矩阵维护标记下传和区间和更新(斐波那契的转移和求和矩阵)。
P4247 [清华集训2012]序列操作
有 \(c \le 20\),可以在线段树上维护答案数组 \(ans\),\(ans[i]\)表示选 \(i\) 个数的答案。
1.区间信息合并。易得有 \(\displaystyle ans[i]=\sum_{j=0}^{i}ans_l[j]*ans_r[i-j]\)。其中 \(ans_l\) 和 \(ans_r\) 是线段树上左右子区间的答案数组。
2.区间取相反数方式。对于 \(ans[i]\),若 \(i\) 为偶数,答案不变;若 \(i\) 为奇数,答案变成相反数。
3.区间加的更新方式。较为困难,待补全。