jzoj3508NOIP2013模拟11.5B组DAY 1 (7.12)HASH好元素(good)
Posted SSL_ZZL
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了jzoj3508NOIP2013模拟11.5B组DAY 1 (7.12)HASH好元素(good)相关的知识,希望对你有一定的参考价值。
【NOIP2013模拟11.5B组】好元素
题面
【jzoj】【3508】【NOIP2013模拟11.5B组】好元素(good)
Description
小A一直认为,如果在一个由N个整数组成的数列An中,存在Am + An + Ap = Ai(1 <= m, n, p < i)(m, n, p可以相同)的话,Ai就是一个“好元素”。现在,小A有一个数列,他想知道这个数列中有多少个“好元素”,请你帮帮他。
Input
第一行只有一个正整数N,意义如上。
第二行包含N个整数,表示数列An。
Output
输出一个整数,表示这个数列中“好元素”的个数。
Sample Input
输入1:
2
1 3
输入2:
6
1 2 3 5 7 10
输入3:
3
-1 2 0
Sample Output
输出1:
1
输出2:
4
输出3:
1
Data Constraint
对于10%的数据 1<=N<=10
对于40%的数据 1<=N<=500 − 1 0 5 < = A i < = 1 0 5 -10^5<=Ai<=10^5 −105<=Ai<=105
对于70%的数据 1<=N<=5000 − 1 0 6 < = A i < = 1 0 6 -10^6<=Ai<=10^6 −106<=Ai<=106
对于100%的数据 1<=N<=5000 − 1 0 9 < = A i < = 1 0 9 -10^9<=Ai<=10^9 −109<=Ai<=109
解题思路
先考虑
A
m
+
A
n
+
A
p
=
A
i
A_m+A_n+A_p=A_i
Am+An+Ap=Ai
搞三重循环枚举m,n,p,搞个桶统计可以组成的数,再枚举i,判断
A
i
A_i
Ai可不可以组成
可以发现
A
m
+
A
n
=
A
i
−
A
p
A_m+A_n=A_i-A_p
Am+An=Ai−Ap会更优
简单来说就是,两重循环 * 2(一个是求
A
m
+
A
n
A_m+A_n
Am+An,放进桶里,一个是求
A
i
−
A
p
A_i-A_p
Ai−Ap存不存在)
∵
−
1
0
9
<
=
A
i
<
=
1
0
9
-10^9<=Ai<=10^9
−109<=Ai<=109
∴ 要用hash当桶
hash板子题
tips
因为1 <= m, n, p < i
做i时,i-1的时候就已经把1 <=m, n< i(1 <=m, n<= i - 1)给放进hash里了
Code
#include <iostream>
#include <cstring>
#include <cstdio>
using namespace std;
const long long Mod = 25000003;
int n, ans;
long long a[5100], hash[Mod + 100], now, P;
void HASH(long long x) {
long long cnt = (x % Mod + Mod) % Mod, i = 0;
while(i < Mod && hash[(cnt + i) % Mod] != P && hash[(cnt + i) % Mod] != x)
i++;
if(hash[(cnt + i) % Mod] == P)
hash[(cnt + i) % Mod] = x;
}
int find(long long x) {
long long cnt = (x % Mod + Mod) % Mod, i = 0;
while(i < Mod && hash[(cnt + i) % Mod] != P && hash[(cnt + i) % Mod] != x)
i++;
return (hash[(cnt + i) % Mod] == x);
}
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]);
memset(hash, -Mod, sizeof(hash));
P = hash[1];
for(int i = 1; i <= n; i++) {
for(int j = 1; j < i; j++) //即p
if(find(a[i] - a[j])) {
ans++;
break;
}
for(int j = 1; j <= i; j++) //即n
HASH(a[i] + a[j]); //tips //因为m是1到n,和i相同且同步增长,所以直接用i循环替代m
}
printf("%d", ans);
}
以上是关于jzoj3508NOIP2013模拟11.5B组DAY 1 (7.12)HASH好元素(good)的主要内容,如果未能解决你的问题,请参考以下文章
jzoj3515NOIP2013模拟11.6B组二分DP软件公司
[jzoj]3506.NOIP2013模拟11.4A组善良的精灵(fairy)(深度优先生成树)
jzoj3505NOIP2013模拟11.4A组组合逆元积木
jzoj3523NOIP2013模拟11.7A组树上倍增JIH的玩偶(tree)