题目描述
给出数列A,当Ai = Am + An + Ap(m,n,p < i)时,我们称Ai为好元素,求数列A中好元素的个数
样例输入
6
1 2 3 5 7 10
样例输出
4
思路
题目中的等式移项可得
A
m
+
A
n
=
A
i
−
A
p
A_m + A_n = A_i - A_p
Am+An=Ai−Ap
那么我们预处理
A
m
+
A
n
A_m + A_n
Am+An即可
但是这两个数的和可能很大,所以用hash表来存储这个值
代码
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<map>
#define ll long long
using namespace std;
const int mo = 25000003;
ll a[5005];
int p, ans, n, b[25000005];
int hash(int x)
{
return (x % mo + mo) % mo;
}//求哈希值
int find(int x)
{
if(x == 0) {
p = 1;//p表示是否有和为0
return 0;
}
int g = hash(x);
if(b[g] && b[g] != x)
{
g++;
if(g > mo) g = 1;
}
return g;
}//查找数值的位置
int main()
{
freopen("good.in", "r", stdin);
freopen("good.out", "w", stdout);
scanf("%d", &n);
for(int i = 1; i <= n; ++i)
scanf("%lld", &a[i]);
for(int i = 1; i <= n; ++i) {
for(int j = 1; j < i; ++j) {
ll t = a[i - 1] + a[j];
b[find(t)] = t;
}
for(int j = 1; j < i; ++j)
{
ll t = a[i] - a[j];
if(t == 0 && p == 1) {
ans++;
break;
}//零需要特判
if(t != 0 && b[find(t)] == t) {//对比判断是否有这个和
ans++;
break;
}
}
}
printf("%d", ans);
return 0;
fclose(stdin);
fclose(stdout);
}