1 条题解

  • 0
    @ 2025-11-4 9:32:08

    1. 题意理解

    我们要求满足以下条件的非负整数 xx 的个数(x<Tx < T):

    $$x \bmod P \in A \quad \text{且} \quad x \bmod Q \in B $$

    其中 AA 是模 PP 的余数集合,BB 是模 QQ 的余数集合。


    2. 直接枚举不可行

    TT 最大到 101810^{18},不能直接枚举 xx


    3. 转化为同余方程组

    条件等价于:

    $$\begin{cases} x \equiv a \pmod{P}, & a \in A \\ x \equiv b \pmod{Q}, & b \in B \end{cases} $$

    对于每一对 (a,b)(a,b),我们要求解同余方程组:

    $$x \equiv a \ (\text{mod } P),\quad x \equiv b \ (\text{mod } Q) $$

    4. 方程组解的结构

    d=gcd(P,Q)d = \gcd(P, Q)

    方程组有解当且仅当

    ab(modd)a \equiv b \pmod{d}

    因为 xa(modP)    xa(modd)x \equiv a \pmod{P} \implies x \equiv a \pmod{d}
    xb(modQ)    xb(modd)x \equiv b \pmod{Q} \implies x \equiv b \pmod{d}
    所以必须有 amodd=bmodda \bmod d = b \bmod d

    如果有解,则解在模 lcm(P,Q)\mathrm{lcm}(P, Q) 下唯一。


    4.1 有解时的通解

    P=dpP = d \cdot p, Q=dqQ = d \cdot q,其中 gcd(p,q)=1\gcd(p, q) = 1

    方程组等价于:

    x=a+Ptx = a + P t

    代入第二个方程:

    a+Ptb(modQ)a + P t \equiv b \pmod{Q} dptba(moddq)d p \cdot t \equiv b - a \pmod{d q}

    两边除以 dd(因为 ab(modd)a \equiv b \pmod{d},所以 bab-add 的倍数):

    ptbad(modq)p t \equiv \frac{b-a}{d} \pmod{q}

    由于 gcd(p,q)=1\gcd(p, q) = 1pp 在模 qq 下有逆元 p1p^{-1},所以:

    tp1bad(modq)t \equiv p^{-1} \cdot \frac{b-a}{d} \pmod{q}

    t0t_0 是上面同余式的最小非负解,则:

    t=t0+kq,kZt = t_0 + k q,\quad k \in \mathbb{Z}

    于是:

    x=a+P(t0+kq)=a+Pt0+kPqx = a + P (t_0 + k q) = a + P t_0 + k \cdot P q

    即:

    xa+Pt0(modPq)x \equiv a + P t_0 \pmod{P q}

    M=lcm(P,Q)=Pq=PQdM = \mathrm{lcm}(P, Q) = P q = \frac{P Q}{d}

    所以对于每一对 (a,b)(a,b) 满足 amodd=bmodda \bmod d = b \bmod d,解在模 MM 下唯一,设这个解为 ra,br_{a,b}0ra,b<M0 \le r_{a,b} < M)。


    5. 统计 x<Tx < T 的个数

    对于每一对 (a,b)(a,b) 满足 amodd=bmodda \bmod d = b \bmod d,解的形式为:

    x=ra,b+kM,k0x = r_{a,b} + k M,\quad k \ge 0

    我们要计算 x<Tx < T 的个数。

    即:

    ra,b+kM<Tr_{a,b} + k M < T k<Tra,bMk < \frac{T - r_{a,b}}{M}

    非负整数 kk 的个数为:

    $$\max\left(0, \left\lfloor \frac{T - 1 - r_{a,b}}{M} \right\rfloor + 1 \right) $$

    (注意 xx00 开始,所以 T1T-1 是上界)


    6. 直接枚举 (a,b)(a,b) 不可行

    n,mn, m 最大 10610^6n×mn \times m 太大。


    7. 按余数模 dd 分组

    由于必须有 amodd=bmodda \bmod d = b \bmod d,我们按这个公共余数 rdr_d 分组。

    对于固定的 rdr_d,设:

    • Ard={aAamodd=rd}A_{r_d} = \{ a \in A \mid a \bmod d = r_d \}
    • Brd={bBbmodd=rd}B_{r_d} = \{ b \in B \mid b \bmod d = r_d \}

    那么对于 aArda \in A_{r_d},可以写成 a=rd+daa = r_d + d \cdot a',其中 0a<p0 \le a' < p
    对于 bBrdb \in B_{r_d},可以写成 b=rd+dbb = r_d + d \cdot b',其中 0b<q0 \le b' < q


    8. 化简方程组

    原方程组:

    $$x \equiv r_d + d a' \pmod{P},\quad x \equiv r_d + d b' \pmod{Q} $$

    y=xrddy = \frac{x - r_d}{d}(因为 xrd(modd)x \equiv r_d \pmod{d},所以 xrdx - r_ddd 的倍数),则方程组变为:

    ya(modp),yb(modq)y \equiv a' \pmod{p},\quad y \equiv b' \pmod{q}

    其中 gcd(p,q)=1\gcd(p, q) = 1


    9. 中国剩余定理(CRT)

    因为 gcd(p,q)=1\gcd(p, q) = 1,模 pp 和模 qq 的方程组在模 pqpq 下有唯一解。

    yy0(modpq)y \equiv y_0 \pmod{pq} 是解,其中 0y0<pq0 \le y_0 < pq

    那么:

    $$x = r_d + d y_0 + k \cdot d p q = r_d + d y_0 + k M $$

    这里 M=lcm(P,Q)=dpqM = \mathrm{lcm}(P, Q) = d p q

    所以对于 (a,b)(a', b'),解为:

    xrd+dy0(modM)x \equiv r_d + d \cdot y_0 \pmod{M}

    其中 y0y_0ya(modp)y \equiv a' \pmod{p}yb(modq)y \equiv b' \pmod{q} 的唯一解。


    10. 快速计算所有 (a,b)(a',b') 对应的解

    我们注意到,对于固定的 rdr_d(a,b)(a', b') 来自 A={arddaArd}A' = \{ \frac{a - r_d}{d} \mid a \in A_{r_d} \}B={brddbBrd}B' = \{ \frac{b - r_d}{d} \mid b \in B_{r_d} \}

    由于 gcd(p,q)=1\gcd(p, q) = 1,CRT 建立了一个双射:

    (a,b)y0(a', b') \leftrightarrow y_0

    其中 y0y_0 是模 pqpq 下的唯一解。

    因此,问题转化为:
    对于每个 rdr_d,我们有一个 AZpA' \subset \mathbb{Z}_pBZqB' \subset \mathbb{Z}_q,通过 CRT 映射到 Zpq\mathbb{Z}_{pq} 的一个子集 SrdS_{r_d},然后对每个 sSrds \in S_{r_d},计算 xrd+ds(modM)x \equiv r_d + d s \pmod{M}[0,T1][0, T-1] 中的个数。


    11. 更简单的实现方法

    其实我们可以直接这样:

    1. 枚举 rd=0,1,,d1r_d = 0, 1, \dots, d-1
    2. 对每个 rdr_d,收集 ArdA_{r_d}BrdB_{r_d}
    3. 对每个 aArda \in A_{r_d}bBrdb \in B_{r_d},解同余方程组得到 ra,b[0,M)r_{a,b} \in [0, M)
    4. 用公式 (T1ra,b)/M+1\lfloor (T - 1 - r_{a,b})/M \rfloor + 1(如果 ra,b<Tr_{a,b} < T,否则 0)计数。

    但第 3 步枚举所有对还是可能太大,如果 ArdBrd|A_{r_d}| \cdot |B_{r_d}| 很大。


    12. 利用 CRT 双射优化

    对于固定的 rdr_d,我们建立映射:

    • f:ArdZpf: A_{r_d} \to \mathbb{Z}_pf(a)=(ard)/df(a) = (a - r_d)/d
    • g:BrdZqg: B_{r_d} \to \mathbb{Z}_qg(b)=(brd)/dg(b) = (b - r_d)/d

    CRT 给出双射 $\phi: \mathbb{Z}_p \times \mathbb{Z}_q \to \mathbb{Z}_{pq}$,ϕ(a,b)\phi(a', b') 是模 pqpq 下的唯一解。

    那么 $S_{r_d} = \{ \phi(f(a), g(b)) \mid a \in A_{r_d}, b \in B_{r_d} \}$。

    注意 ϕ\phi 是双射,所以 Srd=ArdBrd|S_{r_d}| = |A_{r_d}| \cdot |B_{r_d}|,但我们可以直接得到 SrdS_{r_d} 而不必枚举所有对:
    实际上 ϕ(f(a),g(b))\phi(f(a), g(b)) 可以写成:

    $$y_0 \equiv a' \cdot q \cdot q^{-1}_p + b' \cdot p \cdot p^{-1}_q \pmod{pq} $$

    其中 qp1q^{-1}_pqqpp 的逆元,pq1p^{-1}_qppqq 的逆元。

    所以:

    y0=(aQ1+bQ2)modpqy_0 = (a' \cdot Q_1 + b' \cdot Q_2) \bmod{pq}

    其中 Q1=q(q1modp)Q_1 = q \cdot (q^{-1} \bmod p)Q2=p(p1modq)Q_2 = p \cdot (p^{-1} \bmod q) 是 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} \}$。

    这仍然需要枚举所有对,但我们可以用卷积思想(因为模 pqpq 加法)?但 pqpq 可能很大。


    13. 实际可行的方法(P,Q106P, Q \le 10^6

    由于 P,Q106P, Q \le 10^6d106d \le 10^6,且 rdArd=n\sum_{r_d} |A_{r_d}| = nrdBrd=m\sum_{r_d} |B_{r_d}| = m,最坏情况是某个 rdr_dArdBrd|A_{r_d}| \cdot |B_{r_d}| 很大,但平均情况下可能可接受。

    我们可以直接枚举 rdr_d,然后枚举 ArdA_{r_d}BrdB_{r_d},解方程组。

    解方程组的方法:

    • 用扩展欧几里得解 pt(ba)/d(modq)p t \equiv (b-a)/d \pmod{q} 得到 t0t_0,然后 ra,b=(a+Pt0)modMr_{a,b} = (a + P t_0) \bmod M

    复杂度:最坏 O(nm)O(n m),但数据随机可能较快。


    14. 对于大数据(n,mn, m 大但 P,QP, Q 中等)

    我们可以用 meet-in-the-middle:

    对于每个 rdr_d,枚举 aArda \in A_{r_d},计算 a=(ard)/da' = (a - r_d)/d,解 ya(modp)y \equiv a' \pmod{p},通解 y=a+kpy = a' + k p

    对于每个 bBrdb \in B_{r_d},解 yb(modq)y \equiv b' \pmod{q},通解 y=b+lqy = b' + l q

    我们要 a+kp=b+lqa' + k p = b' + l q,即 kplq=bak p - l q = b' - a'

    由于 gcd(p,q)=1\gcd(p, q) = 1k(ba)p1(modq)k \equiv (b' - a') \cdot p^{-1} \pmod{q}

    所以对每个 (a,b)(a', b')kkqq 唯一确定,即 yypqpq 唯一确定。

    这样我们仍要枚举所有对,但可以在 BrdB_{r_d}bb' 分组,对每个 aa' 直接找到对应的 bb' 来批量计算?这里 bb' 是固定的集合,所以还是需要枚举。


    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. 总结

    这道题的核心是将条件转化为同余方程组,利用 gcd(P,Q)\gcd(P, Q) 分组,再运用中国剩余定理将问题化到模 lcm(P,Q)\mathrm{lcm}(P, Q) 下,最后利用除法计数公式统计解数。大数据下需要进一步优化枚举对的过程,例如用循环卷积或二维偏序。

    • 1

    信息

    ID
    4932
    时间
    1000ms
    内存
    256MiB
    难度
    10
    标签
    递交数
    1
    已通过
    1
    上传者