【SSL】2378 &【洛谷】P1102A-B数对
题目描述
出题是一件痛苦的事情!
相同的题目看多了也会有审美疲劳,于是我舍弃了大家所熟悉的 A+B Problem,改用 A-B 了哈哈!
好吧,题目是这样的:给出一串数以及一个数字 C,要求计算出所有 A−B=C 的数对的个数(不同位置的数字一样的数对算不同的数对)。
输入格式
输入共两行。
第一行,两个整数N,C。
第二行,N 个整数,作为要求处理的那串数。
输出格式
一行,表示该串数中包含的满足A−B=C 的数对的个数。
输入输出样例
输入
4 1
1 1 2 3
输出
3
说明/提示
对于75% 的数据,1≤N≤2000。
对于 100% 的数据,1≤N≤200000 。
保证所有输入数据都在 32 位带符号整数范围内。
思路
A-B=C
B+C=A
用HASH.
用一个数组保存出现次数。
特判0.
代码
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
long long a[200010],n,c,hs[1000010],cs[1000010],an,bn,m=1000000,p=900007;
long long HASH(long long x)//函数
{
x%=p;x+=p;
return x%p;
}
long long locate(long long x)//x定位
{
long long i,w=HASH(x);
for(i=0;i<m&&hs[(w+i)%m]!=0&&hs[(w+i)%m]!=x;i++);
return (w+i)%m;
}
int main()
{
long long i,t,n,c,x,w,ans=0,zero=0;
scanf("%lld%lld",&n,&c);
for(i=1;i<=n;i++)
{
scanf("%lld",&a[i]);
x=a[i]+c;
if(x==0)//特判0
zero++;
else
{
w=locate(x);//插入x
hs[w]=x;
cs[w]++;
}
}
for(i=1;i<=n;i++)
{
if(a[i]==0)//特判0
ans+=zero;
else
{
w=locate(a[i]);
ans+=(hs[w]==a[i])*cs[w];
}
}
printf("%lld",ans);
return 0;
}