1 条题解
-
0
1. 题意理解
我们要求满足以下条件的非负整数 的个数():
$$x \bmod P \in A \quad \text{且} \quad x \bmod Q \in B $$其中 是模 的余数集合, 是模 的余数集合。
2. 直接枚举不可行
最大到 ,不能直接枚举 。
3. 转化为同余方程组
条件等价于:
$$\begin{cases} x \equiv a \pmod{P}, & a \in A \\ x \equiv b \pmod{Q}, & b \in B \end{cases} $$对于每一对 ,我们要求解同余方程组:
$$x \equiv a \ (\text{mod } P),\quad x \equiv b \ (\text{mod } Q) $$
4. 方程组解的结构
设 。
方程组有解当且仅当
因为 ,
,
所以必须有 。如果有解,则解在模 下唯一。
4.1 有解时的通解
设 , ,其中 。
方程组等价于:
代入第二个方程:
两边除以 (因为 ,所以 是 的倍数):
由于 , 在模 下有逆元 ,所以:
设 是上面同余式的最小非负解,则:
于是:
即:
记 。
所以对于每一对 满足 ,解在模 下唯一,设这个解为 ()。
5. 统计 的个数
对于每一对 满足 ,解的形式为:
我们要计算 的个数。
即:
非负整数 的个数为:
$$\max\left(0, \left\lfloor \frac{T - 1 - r_{a,b}}{M} \right\rfloor + 1 \right) $$(注意 从 开始,所以 是上界)
6. 直接枚举 不可行
最大 , 太大。
7. 按余数模 分组
由于必须有 ,我们按这个公共余数 分组。
对于固定的 ,设:
那么对于 ,可以写成 ,其中 。
对于 ,可以写成 ,其中 。
8. 化简方程组
原方程组:
$$x \equiv r_d + d a' \pmod{P},\quad x \equiv r_d + d b' \pmod{Q} $$令 (因为 ,所以 是 的倍数),则方程组变为:
其中 。
9. 中国剩余定理(CRT)
因为 ,模 和模 的方程组在模 下有唯一解。
设 是解,其中 。
那么:
$$x = r_d + d y_0 + k \cdot d p q = r_d + d y_0 + k M $$这里 。
所以对于 ,解为:
其中 是 和 的唯一解。
10. 快速计算所有 对应的解
我们注意到,对于固定的 , 来自 和 。
由于 ,CRT 建立了一个双射:
其中 是模 下的唯一解。
因此,问题转化为:
对于每个 ,我们有一个 ,,通过 CRT 映射到 的一个子集 ,然后对每个 ,计算 在 中的个数。
11. 更简单的实现方法
其实我们可以直接这样:
- 枚举 。
- 对每个 ,收集 和 。
- 对每个 和 ,解同余方程组得到 。
- 用公式 (如果 ,否则 0)计数。
但第 3 步枚举所有对还是可能太大,如果 很大。
12. 利用 CRT 双射优化
对于固定的 ,我们建立映射:
- ,。
- ,。
CRT 给出双射 $\phi: \mathbb{Z}_p \times \mathbb{Z}_q \to \mathbb{Z}_{pq}$, 是模 下的唯一解。
那么 $S_{r_d} = \{ \phi(f(a), g(b)) \mid a \in A_{r_d}, b \in B_{r_d} \}$。
注意 是双射,所以 ,但我们可以直接得到 而不必枚举所有对:
$$y_0 \equiv a' \cdot q \cdot q^{-1}_p + b' \cdot p \cdot p^{-1}_q \pmod{pq} $$
实际上 可以写成:其中 是 模 的逆元, 是 模 的逆元。
所以:
其中 , 是 CRT 系数。
于是 $S_{r_d} = \{ (f(a) \cdot Q_1 + g(b) \cdot Q_2) \bmod{pq} \mid a \in A_{r_d}, b \in B_{r_d} \}$。
这仍然需要枚举所有对,但我们可以用卷积思想(因为模 加法)?但 可能很大。
13. 实际可行的方法()
由于 ,,且 ,,最坏情况是某个 的 很大,但平均情况下可能可接受。
我们可以直接枚举 ,然后枚举 和 ,解方程组。
解方程组的方法:
- 用扩展欧几里得解 得到 ,然后 。
复杂度:最坏 ,但数据随机可能较快。
14. 对于大数据( 大但 中等)
我们可以用 meet-in-the-middle:
对于每个 ,枚举 ,计算 ,解 ,通解 。
对于每个 ,解 ,通解 。
我们要 ,即 。
由于 ,。
所以对每个 , 模 唯一确定,即 模 唯一确定。
这样我们仍要枚举所有对,但可以在 按 分组,对每个 直接找到对应的 来批量计算?这里 是固定的集合,所以还是需要枚举。
15. 实现方案(直接枚举对,针对小数据)
对于大数据,正解需要用循环卷积或二维偏序,但这里给出直接法的框架:
#include <bits/stdc++.h> using namespace std; using ll = long long; ll exgcd(ll a, ll b, ll &x, ll &y) { if (!b) { x = 1; y = 0; return a; } ll d = exgcd(b, a % b, y, x); y -= a / b * x; return d; } ll inv(ll a, ll m) { ll x, y; exgcd(a, m, x, y); return (x % m + m) % m; } int main() { ll P, Q, T; int n, m; cin >> P >> Q >> n >> m >> T; vector<int> A(n), B(m); for (int i = 0; i < n; i++) cin >> A[i]; for (int i = 0; i < m; i++) cin >> B[i]; ll d = gcd(P, Q); ll p = P / d, q = Q / d; ll M = P * q; // lcm(P, Q) // 按 r_d 分组 vector<vector<int>> Ag(d), Bg(d); for (int a : A) Ag[a % d].push_back(a); for (int b : B) Bg[b % d].push_back(b); ll ans = 0; ll inv_p = inv(p, q); for (int r = 0; r < d; r++) { if (Ag[r].empty() || Bg[r].empty()) continue; for (int a : Ag[r]) { for (int b : Bg[r]) { // 解方程组 // x = a + P t // a + P t ≡ b (mod Q) // P t ≡ b - a (mod Q) // d p t ≡ b - a (mod d q) // p t ≡ (b - a)/d (mod q) ll rhs = (b - a) / d; ll t0 = (rhs * inv_p) % q; if (t0 < 0) t0 += q; ll x0 = a + P * t0; // 解在模 M 下唯一 x0 %= M; if (x0 < 0) x0 += M; // 计算 x0 + k M < T 的个数 if (x0 < T) { ans += (T - 1 - x0) / M + 1; } } } } cout << ans << endl; return 0; }
16. 总结
这道题的核心是将条件转化为同余方程组,利用 分组,再运用中国剩余定理将问题化到模 下,最后利用除法计数公式统计解数。大数据下需要进一步优化枚举对的过程,例如用循环卷积或二维偏序。
- 1
信息
- ID
- 4932
- 时间
- 1000ms
- 内存
- 256MiB
- 难度
- 10
- 标签
- 递交数
- 1
- 已通过
- 1
- 上传者