题意#
给定 个正整数 ,求出任意一组 使得 .
.
分析#
首先考虑暴力,我们开一个 大小的桶,记录已经找到的和,然后 地暴力枚举,直到桶中有元素出现过 次,并且满足 互不相同即可。
又考虑到这只是 div2.
的 C
题,在这个数据范围上的 做法经过尝试后都行不通。
赛后,我们才知道:非常不幸,这题是结论题。
结论:上面的暴力做法的时间复杂度为:, 为 的值域。
证明#
首先,如果我们找到了四组两两不完全相同的 ,使得:
那么就可以找到满足条件的 了。
这个结论是非常自然的,简单分类讨论就可以证明。对四个数对中,有多少个 相同进行讨论:
- 如果有四个数对的 相同,那么 ,所以 是可行的解。
- 如果有三个数对的 相同,不妨设 与另外三个数不同,那么 就是一组可行解。
- 对于其他情况,显然能找到满足题意的 .
因此,我们只需要用 的暴力做法,最差情况是:所输出的答案的 值出现四次。
所有 的可能值只有 种,根据抽屉原理,程序复杂度不超过 ,可以通过。
代码#
#include <bits/stdc++.h>
using namespace std;
const int MAXN = 2e5 + 10, MAXC = 2e6 + 5e5 + 10;
int n;
int x[MAXC << 1], y[MAXC << 1];
int a[MAXN], cnt[MAXC << 1];
bool have_ans;
int main() {
scanf("%d", &n);
for(int i = 1; i <= n; i++) {
scanf("%d", &a[i]);
}
for(int i = 1; i <= n; i++) {
for(int j = i + 1; j <= n; j++) {
if(cnt[a[i] + a[j]]) {
if(x[a[i] + a[j]] != i && y[a[i] + a[j]] != i
&& x[a[i] + a[j]] != j && y[a[i] + a[j]] != j) {
cout << "YES" << endl << i << " " << j << " " << x[a[i] + a[j]] << " " << y[a[i] + a[j]] << endl;
return 0;
}
} else {
cnt[a[i] + a[j]]++;
x[a[i] + a[j]] = i; y[a[i] + a[j]] = j;
}
}
}
cout << "NO" << endl;
return 0;
}
cpp