【哈希表】好元素(good)

题目描述

给出数列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=AiAp
那么我们预处理 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);
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值