手写哈希表bool find(int x)
开放寻址法
int find(int x){
int t =(x % N + N) % N;/正数负数都存到里面 找个位置给他
while(h[t] != null && h[t] != x){//如果这个位置有值 但是不是那个位置 就找下个位置
t++;
if(t==N) t=0;//到了尽头回去
}
return t;
}
LL find(int x,int t){//哈希记录两个值
LL key = r * 100ll + t;/正数负数都存到里面 找个位置给他
int k = key % M;
while(h[key] != -1 && h[K] != key){//如果这个位置有值 但是不是那个位置 就找下个位置
if( ++ k == M ) k=0;//到了尽头回去
}
if(h[k]== -1) h[k]=key ,cnt[k]=0;
return k;//找到了
}
https://www.acwing.com/problem/content/4614/
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
typedef long long LL;
const int N = 200010, M = 10000007;
int n, m;
int a[N];
LL h[M];
int cnt[M];
int find(int r, int t)
{
LL key = r * 100ll + t;//拼接
int k = key % M;
while (h[k] != -1 && h[k] != key)
if ( ++ k == M)
k = 0;
if (h[k] == -1) h[k] = key, cnt[k] = 0;
return k;
}
LL work()
{
LL res = 0;
memset(h, -1, sizeof h);
for (int i = 0; i < n; i ++ )
{
int r = a[i] % m;//-a[i]的余数
if (r) r = m - r;
int t = 0, x = a[i];
while (x) t ++, x /= 10;
res += cnt[find(r, t)];//找到那个数
for (int j = 1, x = 10; j <= 10; j ++, x = x * 10ll % m)
cnt[find((LL)a[i] * x % m, j)] ++ ;//存对于ai每个数 * k次10的结果
}
return res;
}
int main()
{
scanf("%d%d", &n, &m);
for (int i = 0; i < n; i ++ ) scanf("%d", &a[i]);
LL res = work();//从左往右 求 然后reverse 再求一遍
reverse(a, a + n);
res += work();
printf("%lld\n", res);
return 0;
}