省选模拟71 题解
A. 王子
这个数据范围加上很奇怪的限制,其实就应该是网络流了。
可以首先钦定选择了 $A$ 类,然后将其中的一些替换为 $B$ 类。
其实与志愿者招募那个题挺像的,只不过原来是对于每个点选择 $[l,r]$ 个区间。
但是现在的问题是要求每个区间选择 $[l,r]$ 个数点。
其实并不难处理,将 $n-k+1$ 个区间视作 $n-k+2$ 个连成一条链的点之间的边即可。
这样每个点能造成的贡献其实就是一段连续区间,与志愿者招募一题很像了。
但是还有一个问题是,在本题中要求最大的收益,但是直接建图是存在正环的。
所以这个最大费用流就没得跑了。
考虑这样一个事情,一般的上下界网络流是钦定下界,然后去流上界-下界。
其实另一种做法是钦定上界,建反向边同样流上界-下界表示退流。
这样的话其实可以结合两种做法,只建负边权的边就可以解决这个问题。
B. 遇见
这个题的 $n^2$ 做法是显然的,然后发现 $n \leq 30000$ 而且时限还开了 $3s$。
那直接打个暴力,顺便卡卡常就结束了。
正解是考虑给每种数随机一个权值,然后区间 $[l,r]$ 成为答案仅当 $sum_r \oplus sum_{l-1} \oplus s_{l,r}=0$。
其中 $sum_i$ 表示前缀异或和,$s_{l,r}$ 表示 $[l,r]$ 区间内出现的数的异或和。
容易发现这是一个 $0/1\ trie$ 树问题,然后难点在于维护后者。
考虑每次移动右端点,更新可以更新的 $s_{l,r}$,这是一段连续的区间并且左端点是容易找到的。
所以分块维护这个 $0/1 \ tire$ 树,每次打个标记就好了。
C. 字符串
显然这个问题要用 AC 自动机解决,然后发现不会做。
看数据范围,有一个很奇妙的性质是点数 $\leq 50$。
加上循环这个玩意,就可以联想到这个东西一定是存在循环节的。
假设当前 $str$ 的长度为 $len$,那循环节的长度一定不超过 $50*len$。
所以暴力找循环节是可以接受的。
部分分提示了一些东西,比如可以用一个珂朵莉树来维护字符串 $S$。
点数 $\leq 50$是一个很好的东西,还有一个可以挖掘到的性质是 tire 树的深度是 $\leq 50$的。
因为 AC 自动机维护的是后缀,那也就是说对于每次我们只关注每个点的前 $50$ 个字符就足以得到当前状态。
考虑维护一个数组 $f$, $f_i$ 表示把 $S[1:i]$ 丢到自动机上匹配,得到的以 $r$ 为右端点的子串个数。
对于每次修改,只需要考虑循环节、循环节之前的部分、 $r$ 之后的不超过 $50$ 个字符。
对于循环节内的部分,用线段树区间覆盖即可维护。另外两者可以直接暴力。
对于每次询问,只需要将 $[l,r]$ 拆分为 $[l,l+50]$ 和 $[l+51,r]$。
前者长度很小,可以暴力维护。后者已经与左端点 $l$ 无关了,所以可以直接用 $f$ 数组,所以这题就做完了。