25.11.10联考题解
A
转化题意,变成求这个图划分成若干团的最小改变边数,注意 \(n\le17\) 于是子集 dp \(\mathcal O(3^n)\) 没了,已经能过就不管了()。
B
哎呀这不开一个堆维护一下串就好了?我们用一个二元组 \((l,r)\) 代表一个串,用堆维护,注意最开始加入 \(\min(n,k)\) 个然后每次右端点拓展一个即可。比较字符串怎么办?显然二分哈希,时间复杂度 \(\mathcal O(k\log^2n)\)。
C
生成函数做法
考虑一个物品 \(i\) 的贡献是 \(\sum_{k\ge0}x^{ka_i}\)。写成封闭形式是 \(1\over1-x^{a_i}\),然后答案显然是:
这个直接 Bostan-Mori 做完了,时间复杂度 \(\mathcal O(na\log na\log V+n^2a)\)。
背包做法
考虑大范围并且要求恰好容量为 \(V\) 的题我们可以二进制分组,这样就转换成了一个物品在这一位是否选择的问题。于是设 \(f_{i,j}\) 表示考虑到了二进制下第 \(i\) 位,当期位的和为 \(j\) 的方案数。转移就是正常背包即可。注意每次做完一位后要处理进位的问题,有 \(f_{i+1,\lfloor{j\over2}\rfloor}\leftarrow f_{i,j}\)。时间复杂度 \(\mathcal O(n^2a\log V)\)。
D
一个最直接的想法就是找出每个区间是否合法做,现在考虑如何优化找区间的过程。显然有意义的区间只有 \(\mathcal O(n)\) 个,因为答案不超过 n。我们考虑枚举一下每个数作为绝对众数时候有什么区间有用。现在假设枚举的是 \(col\),考虑找出其在原序列的位置,现在我们扫一遍这些位置,尝试以一个位置作为右端点时候找左端点的位置。有一个比较基础的转化是我们可以将 \(a_i=col\) 的数看作 1,否则看作 -1,这样我们每次就是去找和大于 0 的区间。考虑以一个位置作为右端点那么我们依次往前看能够和 1 匹配的第一个还没有匹配的 -1,并查集简单维护即可;右边同理。这样我们能够找出 \(3m\) 个有效的点,因为我们找的是边界所以合法的区间一定在这些点上。我们考察每个关键点组成的连续段,维护一个前缀和,于是合法的区间就是满足 \(s_{l-1}<s_r\) 的区间。但是直接连边肯定复杂的爆炸,考虑如果有 \(s_{l-1}+2<s_r\) 那么我们一定能够找到一个中转点 \(mid\) 满足 \((l,mid)\) 和 \((mid,r)\) 都有连边。原因是中间的点中能多出至少 2 个 \(col\) 让整个区间内部成为一个连通块,于是我们每次就处理 \(s_r-s_{l-1}<3\) 的情况即可,复杂度 \(\mathcal O(n\log n)\)。

浙公网安备 33010602011771号