1 条题解
-
0
B. 水母与满天星 详细题解
问题重述
给定两个长度为的排列和,元素均为的整数。需要计算数组,其中:
$$r_i = \max_{j=0}^{i} \left( 2^{p_j} + 2^{q_{i-j}} \right) \quad \text{对于 } 0 \le i \le n-1 $$输出所有对取模的结果。
核心难点分析
1. 如何快速比较和
直接计算幂次并比较数值可能超出整数范围,但注意到在二进制表示中只有第位为。因此:
- 若且,则
- 比较两个形如的数,等价于比较它们的二进制最高位:
- 首先比较最大值与
- 若最大值相等,再比较次大值
2. 排列性质的作用
题目强调和是排列,这意味着:
- 每个值到在中恰好出现一次
- 每个值到在中恰好出现一次
这个性质确保了:
- 当我们遍历索引时,当前看到的和的最大值会单调递增
- 每个最大值只会在一个位置出现,便于跟踪
算法核心思想
前缀最大值跟踪
定义:
- = 当前已遍历的中最大值所在位置
- = 当前已遍历的中最大值所在位置
对于固定的,考虑所有:
- 表达式为
关键引理
对于任意,最大值一定出现在以下两种情况之一:
- 固定取当前最大值:取,得到
- 固定取当前最大值:取,得到
证明:假设最大值由和贡献,且。若不是当前的最大值,则存在使得。那么取,得到一定大于等于原值(第一项更大,第二项可能不同)。同理可证部分。因此,最大值必然可以由至少一个部分取当前最大值达到。
算法流程
设:
- = 当前中最大值的位置
- = 当前中最大值的位置
遍历从到:
步骤 1:更新最大值位置
- 若,则
- 若,则
步骤 2:根据和的关系计算
情况 1: 此时是当前所有数中的最大值,因此最大值必定由贡献:
情况 2: 此时是当前所有数中的最大值,因此最大值必定由贡献:
情况 3: 两个最大值相等,需要比较次大项:
$$r_k = 2^{p[i]} + \max\left(2^{q_{k-i}}, 2^{p_{k-j}}\right) $$
标程解析
const int N = 1e5 + 5, Mod = 998244353; int n = 0, s[N] = {}, p[N] = {}, q[N] = {}, r[N] = {}; int main(){ // 预计算 $2^i \bmod MOD$ s[0] = 1; for(int i = 1 ; i < N ; i ++) s[i] = s[i - 1] * 2 % Mod; scanf("%d", &T); while(T --) solve(); return 0; }预计算数组
s:s[i]存储,避免重复计算。inline void solve(){ scanf("%d", &n); for(int i = 0 ; i < n ; i ++) scanf("%d", &p[i]); for(int i = 0 ; i < n ; i ++) scanf("%d", &q[i]); for(int i = 0, j = 0, k = 0 ; k < n ; k ++){ // 更新当前最大值的位置 if(p[k] > p[i]) i = k; if(q[k] > q[j]) j = k; // 根据情况计算 $r_k$ if(p[i] != q[j]){ if(p[i] > q[j]) printf("%d ", (s[p[i]] + s[q[k - i]]) % Mod); else printf("%d ", (s[q[j]] + s[p[k - j]]) % Mod); } else printf("%d ", (s[p[i]] + s[max(q[k - i], p[k - j])]) % Mod); } printf("\n"); }关键点:
i和j始终指向当前已遍历元素中和的最大值位置- 对于每个,只需计算常数个候选值,无需遍历所有
- 利用排列性质确保最大值单调递增,无需回退
正确性证明
定理:对于任意,上述算法计算的等于。
证明:由引理可知,最大值必然可以由以下两种形式之一达到:
- 取,其中是当前最大值的下标
- 取,其中是当前最大值的下标
算法考虑了这两种情况:
- 当时,较大的那个一定是全局最大值,因此只需考虑对应的一种情况
- 当时,两种情况的第一个加数相等,只需比较第二个加数取最大值
因此算法正确。
时间复杂度分析
- 预处理数组:,其中
- 每个测试用例:
- 总复杂度:,完全可行
示例验证
以第一个测试用例为例:
- ,
遍历过程:
:
- 初始:
- 更新后:
- ,,
:
- 更新:,;,
- ,,相等
- $r_1 = 2^{p[1]} + \max(2^{q[1-1]}, 2^{p[1-1]}) = 2^2 + \max(2^{q[0]}, 2^{p[0]}) = 4 + \max(2, 1) = 6$
:
- 保持不变
- ,,相等
- $r_2 = 4 + \max(2^{q[1]}, 2^{p[1]}) = 4 + \max(4, 4) = 8$
输出:,与题目示例一致。
- 1
信息
- ID
- 6173
- 时间
- 1000ms
- 内存
- 256MiB
- 难度
- 2
- 标签
- 递交数
- 7
- 已通过
- 1
- 上传者