题目来源: 2019 ICPC Asia EC Final: H. King
题目来源: XJTUOJ-1223 zxh的一气通贯
题目链接: https://oj.xjtuicpc.com/problem/1223
题面
一共 \(T\) 组数据.
给定素数 \(p\), 以及长度为 \(n\) 的序列 \(a_1,a_2,\cdots, a_n\).
需要找出满足下列条件的子序列 \(b_1,b_2,\cdots,b_m\) 的最大长度:
- 子序列长度 \(m\ge n/2\).
- \(\forall i\in[1,m)\cap\mathbb N\), \(\exists q\in\mathbb N\), s.t. \(qb_i\equiv b_{i+1}\pmod p\). 即子序列在模 \(p\) 意义下是等比子序列.
若不存在这种子序列, 输出 -1
.
数据范围
\[ 1\le T<1000 \]
\[ 1\le n\le2\times10^5 \]
\[ 2\le p\le10^9+7 \]
\[ 1\le a_1,a_2,\cdots,a_n<p \]
保证输入的 \(p\) 是素数. 数据组中 \(n\) 的总和不超过 \(2\times10^5\).
题解
考虑在确定公比 \(q\) 的情况下,
找出最长的等比子序列. 记 \(dp[i]\)
为序列 \(a_i,a_{i+1},\cdots,a_n\)
的最长等比子序列的长度, 其中该等比子序列公比为 \(q\), 首项为 \(a_i\). 则若 \(i\) 之后的第一个 \(qa_i\bmod p\) 位置在 \(a_j\), 则 \[
dp[i]=dp[j]+1
\] 用vector<int>
存储同一个数字 \(a\) 的所有位置, 并用 map
建立
\(a\) 和其所有位置的映射.
由于位置是固定的, 且位置编号单调递增, 故寻找之后第一个 \(qa_i\bmod p\)
的位置可以在映射的所有位置中使用二分查找. 按该方法查找一次的复杂度为
\(O(\log n)\).
边界条件: 找不到 \(a_j\), 则最长等比子序列为 \(a_i\), 长度为 \(1\), \(dp[i]=1\).
确定公比 \(q\) 的情况下, 最长等比子序列的长度为: \[ \max_{1\le i\le n}dp[i] \] 求得长度的复杂度为 \(O(n\log n)\).
若直接枚举公比, 则每个可能的公比都形如 \(a_ia_j^{-1}\bmod p\), 至多有 \(O(n^2)\) 个公比可供选择, 不能接受.
考虑取公比 \(q\) 时, 若以 \(q\) 为公比的子序列长度不小于 \(n/2\), 则可以注意到: 这个子序列一定有一定量的相邻元素对, 在原序列的位置相邻或隔一. 考虑这样的相邻元素对的最小数量 \(s\). 若所有的相邻元素对在原序列的位置都相隔至少 \(2\), 则最多一共有 \((n-1)/3\) 对元素. 但由于子序列长度不小于 \(n/2\), 相邻元素对的数量不小于 \(n/2-1\). 故 \(s\) 的一个下界为: \[ s\ge \frac n2-\frac{n-1}3-1\tag1 \] 这个下界是 \(n/6\) 量级的.
考虑原序列中相邻或隔一的元素对, 每个元素对确定了一个公比 \(a_ia_j^{-1}\bmod p\), 这一共有 \(2n-3\) 个(可以重复的)取值, 而 \(q\) 要在这些取值中出现至少 \(s\) 次. 这是一个必要条件, 可以利用这个必要条件筛选掉不可能满足条件的公比. 使用下界(1)进行筛选, 最终最多只会剩 \(12\) 个左右的公比可能符合条件, 即公比只有 \(O(1)\) 个取值.
总复杂度为 \(O(n\log n)\).
备注
\(s\) 的一个更紧的下界为 \[ s\ge \frac n4-1\tag 2 \] 证明如下: 设有 \(k\) 个相邻元素对在原序列中的位置相隔至少 \(2\), 则有以下不等式: \[ \begin{align}3k+s+1&\le n\tag3\\k+s+1&\ge \left\lceil{\frac n2}\right\rceil\tag4\end{align} \] (3) 减 (4) 可得 \[ k\le \frac n4 \] 而根据 (4) 可知 \[ s\ge\frac n2-k-1\ge\frac n4-1 \]
代码实现
1 |
|
花絮
笔者在现场比赛过程中未能通过本题, 但算法与本文一致. 在复现中使用相同的算法重写, 仍 Wrong Answer. 经排查算法未有错误, Wrong Answer 是代码中某运算未取模导致. 由于此问题, 笔者错失了 ICPC Asia EC Final 的银牌. 在发现这一问题后, 为防止再次出现类似问题, 笔者撰写了模 \(p\) 同余类模板.