1 条题解
-
0
D. Exam in MAC 详解
题目重述
给定一个严格递增的整数集合 ()和一个整数 。要求计算满足 且 且 的整数对 的数量。
思路分析
直接枚举所有 不可行,因为 可达 。需要利用容斥原理,从总对数中减去不合法的对数,再加回被重复减去的部分。
1. 总对数
不考虑任何限制时,满足 的对数为:
$$\text{total} = \sum_{x=0}^{c} (c - x + 1) = \frac{(c+1)(c+2)}{2} $$2. 减去 的对数
对于固定的 ,方程 在 下的解数:
- 的取值范围: 最小为 ,最大为 。
- 由于 ,,所以 从 到 。
- 解的数量为 。
因此,所有 的对数为:
$$\text{sum\_add} = \sum_{v \in s} \left( \left\lfloor \frac{v}{2} \right\rfloor + 1 \right) $$3. 减去 的对数
对于固定的 ,方程 在 下的解数:
- 可以从 到 ,,自动满足 。
- 解的数量为 。
因此,所有 的对数为:
4. 加回同时满足 且 的对数
同时满足两个条件的 对应两个集合中的数 和 。解方程组:
$$\begin{cases} x+y = v \\ y-x = d \end{cases} \Longrightarrow x = \frac{v-d}{2},\quad y = \frac{v+d}{2} $$要求 为非负整数且 ,这等价于:
- 和 同奇偶(否则 非整数)
- (保证 )
- 自动满足 ?因为 ,所以 ,即 恒成立。
因此,对于集合 中的任意两个数 (允许相等),若 且 ,则唯一确定一个合法对 。注意当 时,,也是合法的。
于是,同时满足条件的对数等于:将 中的数按奇偶性分类,设偶数的个数为 ,奇数的个数为 。对于同一奇偶类中的数,任意选取两个(可相同)且第一个不小于第二个,这样的有序对数目为:
其中 为该类的大小。因此,加回的数量为:
$$\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} $$算法步骤
- 读入 和数组 。
- 计算 (注意用 64 位整数)。
- 初始化 。
- 遍历每个 :
- 若 为偶数则 ,否则 。
- 计算 $\text{add\_back} = \frac{\text{even}(\text{even}+1)}{2} + \frac{\text{odd}(\text{odd}+1)}{2}$。
- 输出 $\text{total} - \text{sum\_add} - \text{sum\_diff} + \text{add\_back}$。
时间复杂度 ,空间复杂度 。
代码实现(含注释)
#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; }验证样例
以第一个测试用例为例:。
- $\text{sum\_add} = (1/2+1)+(2/2+1)+(3/2+1)= (0+1)+(1+1)+(1+1)=1+2+2=5$
- $\text{add\_back} = \frac{1\cdot2}{2}+\frac{2\cdot3}{2}=1+3=4$
- ,与输出一致。
注意事项
- 使用
long long避免溢出,因为 可达 ,总对数约为 ,需 64 位整数。 - 集合 已保证严格递增,但算法不依赖该性质(只需元素值)。
- 奇偶分类的正确性源于 与 同奇偶。
- 1
信息
- ID
- 6468
- 时间
- 2000ms
- 内存
- 256MiB
- 难度
- 6
- 标签
- 递交数
- 1
- 已通过
- 1
- 上传者