jzoj3508-好元素【hash,优雅的暴力】

正题


大意

一个序列A,求满足

A n + A m + A p = A i ( n , m , p < i )

这个要求的 A i 的个数


解题思路

我们先移一个项

A n + A m = A i A p

然后用hash表储存 A n + A m 的所有答案,然后到达一个数的时候枚举 p 就可以 O ( n 2 ) 求出答案
玄学的是map库只有40,这个故事告诉我们不要偷懒


代码

#include<cstdio>
#include<algorithm>
#define maxn 25000004
using namespace std;
int n,s,hash[maxn+10],a[5001];
bool v[maxn+10];
int hashmath(int x)
{return (x%maxn+maxn)%maxn;}
int locate(int x)//查找位置
{
    int i=0,w=hashmath(x);
    while (i<maxn&&v[(w+i)%maxn]&&hash[(w+i)%maxn]!=x)
      i++;
    return (w+i)%maxn;
}
void ins(int x)//插入
{
    int w=locate(x);
    hash[w]=x;v[w]=true;
}
bool find(int x)//查找
{
    int w=locate(x);
    if (hash[w]==x&&v[w]) return true;
    else return false;
}
int main()
{
    //freopen("good.in","r",stdin);
    //freopen("good.out","w",stdout);
    scanf("%d",&n);
    for (int i=1;i<=n;i++)
    {
        scanf("%d",&a[i]);
        for (int j=1;j<=i;j++)
        {
          if (i!=j&&find(a[i]-a[j]))//查找
          {
            s++;//统计答案
            break;//退出循环
          }
        }
        for (int j=1;j<=i;j++)
          ins(a[i]+a[j]);//加入新的答案
    }
    printf("%d",s);
}

猜你喜欢

转载自blog.csdn.net/mr_wuyongcong/article/details/81104560