1 条题解

  • 0
    @ 2026-4-7 22:43:08

    D. Exam in MAC 详解

    题目重述

    给定一个严格递增的整数集合 ss0sic0 \le s_i \le c)和一个整数 cc。要求计算满足 0xyc0 \le x \le y \le cx+ysx+y \notin syxsy-x \notin s 的整数对 (x,y)(x,y) 的数量。

    思路分析

    直接枚举所有 (x,y)(x,y) 不可行,因为 cc 可达 10910^9。需要利用容斥原理,从总对数中减去不合法的对数,再加回被重复减去的部分。

    1. 总对数

    不考虑任何限制时,满足 0xyc0 \le x \le y \le c 的对数为:

    $$\text{total} = \sum_{x=0}^{c} (c - x + 1) = \frac{(c+1)(c+2)}{2} $$

    2. 减去 x+ysx+y \in s 的对数

    对于固定的 vsv \in s,方程 x+y=vx+y = v0xyc0 \le x \le y \le c 下的解数:

    • xx 的取值范围:xx 最小为 max(0,vc)\max(0, v-c),最大为 v/2\lfloor v/2 \rfloor
    • 由于 vcv \le cvc0v-c \le 0,所以 xx00v/2\lfloor v/2 \rfloor
    • 解的数量为 v/2+1\lfloor v/2 \rfloor + 1

    因此,所有 x+ysx+y \in s 的对数为:

    $$\text{sum\_add} = \sum_{v \in s} \left( \left\lfloor \frac{v}{2} \right\rfloor + 1 \right) $$

    3. 减去 yxsy-x \in s 的对数

    对于固定的 dsd \in s,方程 yx=dy-x = d0xyc0 \le x \le y \le c 下的解数:

    • xx 可以从 00cdc-dy=x+dy = x+d,自动满足 xyx \le y
    • 解的数量为 cd+1c-d+1

    因此,所有 yxsy-x \in s 的对数为:

    sum_diff=ds(cd+1)\text{sum\_diff} = \sum_{d \in s} (c - d + 1)

    4. 加回同时满足 x+ysx+y \in syxsy-x \in s 的对数

    同时满足两个条件的 (x,y)(x,y) 对应两个集合中的数 v=x+yv = x+yd=yxd = y-x。解方程组:

    $$\begin{cases} x+y = v \\ y-x = d \end{cases} \Longrightarrow x = \frac{v-d}{2},\quad y = \frac{v+d}{2} $$

    要求 x,yx,y 为非负整数且 xyx \le y,这等价于:

    • vvdd 同奇偶(否则 x,yx,y 非整数)
    • vdv \ge d(保证 x0x \ge 0
    • 自动满足 ycy \le c?因为 v,dcv,d \le c,所以 v+d2cv+d \le 2c,即 ycy \le c 恒成立。

    因此,对于集合 ss 中的任意两个数 v,dv,d(允许相等),若 vdv \ge dvd(mod2)v \equiv d \pmod{2},则唯一确定一个合法对 (x,y)(x,y)。注意当 v=dv = d 时,x=0,y=vx=0,y=v,也是合法的。

    于是,同时满足条件的对数等于:将 ss 中的数按奇偶性分类,设偶数的个数为 even\text{even},奇数的个数为 odd\text{odd}。对于同一奇偶类中的数,任意选取两个(可相同)且第一个不小于第二个,这样的有序对数目为:

    m(m+1)2\frac{m(m+1)}{2}

    其中 mm 为该类的大小。因此,加回的数量为:

    $$\text{add\_back} = \frac{\text{even}(\text{even}+1)}{2} + \frac{\text{odd}(\text{odd}+1)}{2} $$

    5. 最终答案

    由容斥原理:

    $$\text{ans} = \text{total} - \text{sum\_add} - \text{sum\_diff} + \text{add\_back} $$

    算法步骤

    1. 读入 n,cn, c 和数组 ss
    2. 计算 total=(c+1)(c+2)2\text{total} = \frac{(c+1)(c+2)}{2}(注意用 64 位整数)。
    3. 初始化 even=0,odd=0\text{even}=0,\text{odd}=0
    4. 遍历每个 sis_i
      • sum_add+=si/2+1\text{sum\_add} \mathrel{+}= s_i/2 + 1
      • sum_diff+=csi+1\text{sum\_diff} \mathrel{+}= c - s_i + 1
      • sis_i 为偶数则 even++\text{even}++,否则 odd++\text{odd}++
    5. 计算 $\text{add\_back} = \frac{\text{even}(\text{even}+1)}{2} + \frac{\text{odd}(\text{odd}+1)}{2}$。
    6. 输出 $\text{total} - \text{sum\_add} - \text{sum\_diff} + \text{add\_back}$。

    时间复杂度 O(n)O(n),空间复杂度 O(1)O(1)

    代码实现(含注释)

    #include <bits/stdc++.h>
    using namespace std;
    using ll = long long;
    
    void solve() {
        int n, c;
        cin >> n >> c;
        vector<int> s(n);
        for (int i = 0; i < n; ++i) cin >> s[i];
    
        ll total = (ll)(c + 1) * (c + 2) / 2;   // 总对数
        ll sum_add = 0, sum_diff = 0;
        int even = 0, odd = 0;
    
        for (int v : s) {
            sum_add += v / 2 + 1;               // x+y = v 的对数
            sum_diff += c - v + 1;              // y-x = v 的对数
            if (v % 2 == 0) ++even;
            else ++odd;
        }
    
        ll add_back = (ll)even * (even + 1) / 2 + (ll)odd * (odd + 1) / 2;
        ll ans = total - sum_add - sum_diff + add_back;
        cout << ans << '\n';
    }
    
    int main() {
        ios::sync_with_stdio(false);
        cin.tie(nullptr);
        int T;
        cin >> T;
        while (T--) solve();
        return 0;
    }
    

    验证样例

    以第一个测试用例为例:n=3,c=3,s={1,2,3}n=3,c=3,s=\{1,2,3\}

    • total=4×52=10\text{total} = \frac{4\times5}{2}=10
    • $\text{sum\_add} = (1/2+1)+(2/2+1)+(3/2+1)= (0+1)+(1+1)+(1+1)=1+2+2=5$
    • sum_diff=(31+1)+(32+1)+(33+1)=3+2+1=6\text{sum\_diff} = (3-1+1)+(3-2+1)+(3-3+1)=3+2+1=6
    • even=1 (2), odd=2 (1,3)\text{even}=1\ (2),\ \text{odd}=2\ (1,3)
    • $\text{add\_back} = \frac{1\cdot2}{2}+\frac{2\cdot3}{2}=1+3=4$
    • ans=1056+4=3\text{ans}=10-5-6+4=3,与输出一致。

    注意事项

    • 使用 long long 避免溢出,因为 cc 可达 10910^9,总对数约为 5×10175\times10^{17},需 64 位整数。
    • 集合 ss 已保证严格递增,但算法不依赖该性质(只需元素值)。
    • 奇偶分类的正确性源于 x+yx+yyxy-x 同奇偶。
    • 1

    信息

    ID
    6468
    时间
    2000ms
    内存
    256MiB
    难度
    6
    标签
    递交数
    1
    已通过
    1
    上传者