专栏文章
题解:AT_arc195_b [ARC195B] Uniform Sum
AT_arc195_b题解参与者 3已保存评论 2
文章操作
快速查看文章及其快照的属性,并进行相关操作。
- 当前评论
- 2 条
- 当前快照
- 1 份
- 快照标识符
- @miptaskf
- 此快照首次捕获于
- 2025/12/03 17:35 3 个月前
- 此快照最后确认于
- 2025/12/03 17:35 3 个月前
令 表示最多能找到多少个对 使得 ,且每个对的 互不相同, 互不相同。比如当 时 。
令数组 中 的个数为 ,数组 中 的个数为 。
如果最终我们希望 ,首先我们会尽可能多地将已经确定的数字(不是 的数字)配对,这样总共会配成 个对。
此时数组 中还剩于有 个 和 个非 ,数组 中有 个 和 个非 。现在这些非 的数已经没法两两配对了(因为上一步匹配完了),因此每个非 的数都会找一个 进行配对。于是 合法等价于 且 。
当然,因为 不能替换为负数,所以 是必要的。
首先特判掉一个特殊情况:如果 且 (即 ),那么直接输出 Yes。这个的含义是,每个非 的数都能找到一个 配对。显然这样是可以构造的,把 取到非常大即可。
现在我们只需要求解所有 就好了。全求出来显然不可能,但显然满足 的 是 级别的。这样复杂度就对了。
但是怎样快速的求出这 个 的值呢?首先将 放到桶里,令 表示 中 的出现次数, 表示 中 的出现次数, 枚举 ,将 加上 即可。
CPP#include <bits/stdc++.h>
using namespace std;
const int N = 2010;
int n, a[N], b[N];
unordered_map<int, int> A, B, f;
signed main() {
cin >> n;
int mx = 0;
for (int i = 1; i <= n; ++ i ) {
cin >> a[i];
A[a[i]] ++ ;
mx = max(mx, a[i]);
}
for (int i = 1; i <= n; ++ i ) {
cin >> b[i];
B[b[i]] ++ ;
mx = max(mx, b[i]);
}
for (auto [i, x] : A)
if (i != -1)
for (auto [j, y] : B)
if (j != -1)
f[i + j] += min(x, y);
if (A[-1] >= n - B[-1]) {
cout << "Yes\n";
return 0;
}
for (auto [i, x] : f)
if (i >= mx && A[-1] >= n - B[-1] - x) {
cout << "Yes\n";
return 0;
}
cout << "No\n";
return 0;
}
相关推荐
评论
共 2 条评论,欢迎与作者交流。
正在加载评论...