Description
在一个 a r r a y array array a a a 中是否存在四个不同的下标 x , y , z , w x,y,z,w x,y,z,w,使得 a x + a y = a z + a w a_x+a_y=a_z+a_w ax+ay=az+aw
Solution
不妨设 s u m = a [ i ] + a [ j ] , 1 ≤ i , j ≤ n , i ≠ j sum=a[i]+a[j],1\le i,j \le n,i \ne j sum=a[i]+a[j],1≤i,j≤n,i=j,对于一个长度为 n n n的 a r r a y array array a a a,从中可以选出 n ∗ ( n − 1 ) 2 \frac {n*(n-1)}2 2n∗(n−1)个 s u m sum sum,当然里面可能有相同的
观察数据范围可以看出, n n n最大值为 2 e 5 2e5 2e5, a [ i ] a[i] a[i]最大值为 2.5 e 6 2.5e6 2.5e6,则 s u m ∈ [ 2 , 5000000 ] sum \in [2,5000000] sum∈[2,5000000]
如果 n ∗ ( n − 1 ) 2 > 5000000 \frac {n*(n-1)}2 >5000000 2n∗(n−1)>5000000,那么必然存在至少两个相同的 s u m sum sum
因此可以直接枚举 n ∗ ( n − 1 ) 2 \frac {n*(n-1)}2 2n∗(n−1)这么多个 s u m sum sum,如果出现相同的,则直接输出即可,时间复杂度为 O ( m i n ( n 2 , n + c ) ) O(min(n^2,n+c)) O(min(n2,n+c))~~(详见Editorial)~~因为最多枚举到 5 e 6 5e6 5e6个就会终止,所以其实一定不会超时
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 5e6+10;
struct Node{
int x,y;
}p[maxn];
int n, a[200000+10];
int main()
{
cin>>n;
for(int i=1;i<=n;i++)
cin>>a[i];
for(int i=1;i<=n-1;i++)
{
for(int j=i+1;j<=n;j++)
{
int sum = a[i] + a[j];
if(p[sum].x==0 || p[sum].y==0)
{
p[sum].x = i;
p[sum].y = j;
}
else
{
if(p[sum].x!=i && p[sum].y!=i && p[sum].x!=j && p[sum].y!=j)
{
printf("YES\n");
printf("%d %d %d %d",p[sum].x,p[sum].y,i,j);
return 0;
}
}
}
}
cout<<"NO";
return 0;
}