[CSP 三十联测] 来者守护 solution
[CSP 三十联测] 来者守护 solution
官方思路感觉属实逆天。
题目描述
- 浮游城上共有 \(N\) 个种族,第 \(i\) 个种族的军队人数为 \(2^{a_i}\),且对任意 \(z\),最多只能找到两个种族 \(i,j\),满足 \(a_i=a_j=z\)。令 \(k=max\{a_i\}\),未来公主想知道一共有多少种方法组合出一支人数为 \(2^{k+1}\) 的队伍(不需要用到所有种族)。
- 一个数字表示方案数,由于答案可能很大,答案对 \(998244353\) 取模。
题目思路
首先排序。
注意对于任意 \(z\),最多只能找到两个种族 \(i,j\),满足 \({a_i=a_j=z} ^{[1]}\)。这是解题的关键。
由题意,对于一组相邻的 \(a_i,a_{i-1}\) 我们可以得出 \(3\) 种情况:
- \(a_i=a_{i-1}\)。对于这一种情况,显然对 \(2^{k+1}\) 有贡献,并且因为 \([1]\),所以他们即使相等,也是来自不同的种族。因此就有 \(2\) 种情况,及选择 \(a_{i-1}\) 或选择 \(a_{i}\)。
- \(a_{i}-a_{i-1}=1\)。对于这种情况,仍然对 \(2^{k+1}\) 贡献 \(1\),即他们的差值。
- \(a_{i}-a_{i-1}>1\)。对于这种情况,对 \(2^{k+1}\) 没有贡献,因为他们的差值为负。因此我们要从后往前进行查找每一组 \(a_i,a_{i-1}\),否则如果从前往后,差值就变成正的了。
但是我们还需要注意一个非常重要的点:
假如我们统计到了 \(sum\) 个 \(a_i=a_{i-1}\),那么只能有 \(sum-1\) 组有两种情况,剩下一种只能有一种情况,证明如下:
- 当 \(a_i=a_{i-1}=k=max\{a_i\}\) 时,它的贡献为 \(2 \cdot 2^{a_i}\),即 \(2 \cdot 2^{k}=2^{k+1}\)(此时 \(a_i,a_{i-1}\) 为最大值)。所以当只有一组 \(a_i,a_{i-1}\) 时,显然有且只有 \(2^{a_i+1} \le 2^{k+1}\)。所以只有这一种情况。
所以,最后的答案为 \(2^{sum-1}\)。
因此,我们可以定义一个 \(sum\) 数组,从 \(sum[1]\) 累加到 \(sum[sum-1]\),然后对 \(998244353\) 取模即可。
复杂度 \(O(n \log n)\)。Code