一、模拟散列表(两种方法)
邻接表
数组(开2~3倍)
#include <iostream>
#include <cstring>
using namespace std;
#define INF 0x7f7f7f7f
const int N = 100003;
int h[N], e[N], ne[N], idx; // 邻接表
int hh[200003]; // 不使用邻接表则需要开2~3倍
void add(int x)
{
int k = (x % N + N) % N; // 确保为正
// e[idx] = x, ne[idx] = h[k], h[k] = idx++;
while(hh[k] != INF) k++;
hh[k] = x;
}
bool findx(int x)
{
int k = (x % N + N) % N;
// for(int i = h[k]; i!=-1; i = ne[i])
// {
// int t = e[i];
// if(t == x) return true;
// }
// return false;
while(hh[k] != INF && hh[k] != x) k++;
if(hh[k] == INF) return false;
return true;
}
int main(void)
{
memset(h, -1, sizeof h);
memset(hh, 0x7f, sizeof hh);
int n, x;
char op[2];
// for(int i = 200001;; i+=2)
// {
// bool flag = true;
// for(int j = 2; j < i/2; j++)
// if(i % j == 0) flag = false;
// if(flag){cout << i << endl; break;}
// }
scanf("%d", &n);
while (n -- )
{
scanf("%s%d", op, &x);
if(op[0] == 'I') add(x);
else
{
if(findx(x)) puts("Yes");
else puts("No");
}
}
return 0;
}
二、字符串哈希
给定一个长度为 n 的字符串,再给定 m 个询问,每个询问包含四个整数 l1, r1, l2, r2。判断[l1, r1], [l2, r2]两个子串是否相同
#include <iostream>
#include <math.h>
using namespace std;
const int N = 1e5+2;
const int P = 13331; // or 131
// 转为P进制, 结果对2^64取余(用ULL类型存储即可)
typedef unsigned long long ULL;
int n, m;
ULL h[N], p[N];
int main()
{
char str[N];
int l1, r1, l2, r2;
scanf("%d%d", &n, &m);
scanf("%s", str);
p[0] = 1;
for(int i = 1; i <= n; i++)
{
h[i] = h[i-1] * P + str[i-1];
p[i] = p[i-1] * P;
}
while (m -- )
{
scanf("%d%d%d%d", &l1, &r1, &l2, &r2);
if(h[r1]-h[l1-1]*p[r1-l1+1] == h[r2]-h[l2-1]*p[r2-l2+1]) puts("Yes");
else puts("No");
}
return 0;
}```