文章目录
- 题目描述
- 解析
- 代码
题目描述

 
解析
如果枚举m,n,p的话是n3的
 会超时
 但我们注意到右边查询只有O(n)
 这就很不平衡
 所以考虑把p移到右边,预处理枚举m、n存到哈希表中
 查询枚举i、p
 这样就把复杂度均摊降到了n2
 但是本题数据较强
 所以我们得保证哈希表的单词查询复杂度近似于O1
 因此我们需要一个1e7左右的质数
 此外,还要注意点的个数和边数都应该是n2级,3e7左右
 好在本题空间复杂度是比较充裕的
 可以通过
代码
#include<bits/stdc++.h>
using namespace std;
#define ll long long
typedef unsigned long long ull;
const int N = 3e7+100;
const int M=1e7+5;
const ll mod=1e7+3;
int n;
int a[5050];
int fi[M],cnt=-1;
int num[N],tot=0;
struct node{int to,nxt;
}p[N];
void addline(int x,int y){p[++cnt]=(node){y,fi[x]};fi[x]=cnt;
}
bool find(int x){int o=x%mod;if(o<0) o+=mod;for(int i=fi[o];~i;i=p[i].nxt){int to=p[i].to;if(num[to]==x) return true;}return false;
}
void put(int x){int o=x%mod;if(o<0) o+=mod;num[++tot]=x;addline(o,tot);
}
int main(){memset(fi,-1,sizeof(fi));//printf("%d",sizeof(num)/1024/1024);scanf("%d",&n);for(int i=1;i<=n;i++) scanf("%d",&a[i]);int ans=0;for(int i=1;i<=n;i++){for(int j=1;j<i;j++){int x=a[i]-a[j];if(find(x)){ans++;break;}}for(int j=1;j<=i;j++){int x=a[i]+a[j];if(!find(x)) put(x);}}printf("%d",ans);return 0;
}
/*
3
1 2 3
4 5 6
7 8 9
5 6 7
8 9 1
2 3 4 
*/