文章目录
- 题目描述
- 解析
- 代码
题目描述
解析
如果枚举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
*/