模拟散列表

维护一个集合,支持如下几种操作:

  1. I x,插入一个数 x;
  2. Q x,询问数 x 是否在集合中出现过;

现在要进行 N 次操作,对于每个询问操作输出对应的结果。

输入格式

第一行包含整数 N,表示操作数量。

接下来 N 行,每行包含一个操作指令,操作指令为 I xQ x 中的一种。

输出格式

对于每个询问指令 Q x,输出一个询问结果,如果 x 在集合中出现过,则输出 Yes,否则输出 No

每个结果占一行。

数据范围

1≤N≤1e5
−1e9≤x≤1e9

输入样例:

1
2
3
4
5
6
5
I 1
I 2
I 3
Q 2
Q 5

输出样例:

1
2
Yes
No

个人代码

ps 个人不会写哈希写了一个树凑合一下用吧(⊙﹏⊙)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
#include<bits/stdc++.h>
using namespace std;
struct Node {
bool val;
Node* children[10];
Node(): val(false) {
for (int i = 0; i <= 9; i++) {
children[i] = nullptr;
}
}
};
Node *z;
Node *f;
void insert(string s) {
Node *cur;
int begins = s[0] == '-';
if (begins == 0) {
cur = z;
} else {
cur = f;
}
for (int i = begins; i < s.size(); i++) {
if (cur->children[s[i] - '0'] == nullptr) {
cur->children[s[i] - '0'] = new Node();
}
cur = cur->children[s[i] - '0'];
}
cur->val = true;
}
bool isLive(string s) {
Node *cur;
int begins = s[0] == '-';
if (begins == 0) {
cur = z;
} else {
cur = f;
}
for (int i = begins; i < s.size(); i++) {
if (cur->children[s[i] - '0'] == nullptr) return false;
cur = cur ->children[s[i] - '0'];
}
return cur->val;
}

int main() {
z = new Node();
f = new Node();
int n;
cin >> n;
while (n--) {
char op;
string val;
cin >> op >> val;
if (op == 'I') {
insert(val);
} else {
if (isLive(val)) {
cout<<"Yes"<<endl;
} else {
cout<<"No"<<endl;
}
}
}

/*
5
I 1
I 2
I 3
Q 2
Q 5
*/
}

板子

开发寻址法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
#include <cstring>
#include <iostream>

using namespace std;

const int N = 200003, null = 0x3f3f3f3f;

int h[N];

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;
}

int main()
{
memset(h, 0x3f, sizeof h);

int n;
scanf("%d", &n);

while (n -- )
{
char op[2];
int x;
scanf("%s%d", op, &x);
if (*op == 'I') h[find(x)] = x;
else
{
if (h[find(x)] == null) puts("No");
else puts("Yes");
}
}

return 0;
}
/*
本质上是先把数据处理一下让他编程可控范围内的数据然后进行向前寻找只要找到一个空的点或者发现自己就可以跳出来了。
*/

拉链法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
#include <cstring>
#include <iostream>

using namespace std;

const int N = 200003;

int h[N], e[N], ne[N], idx;

void insert(int x)
{
int k = (x % N + N) % N;
e[idx] = x;
ne[idx] = h[k];
h[k] = idx ++ ;
}

bool find(int x)
{
int k = (x % N + N) % N;
for (int i = h[k]; i != -1; i = ne[i])
if (e[i] == x)
return true;

return false;
}

int main()
{
int n;
scanf("%d", &n);

memset(h, -1, sizeof h);

while (n -- )
{
char op[2];
int x;
scanf("%s%d", op, &x);

if (*op == 'I') insert(x);
else
{
if (find(x)) puts("Yes");
else puts("No");
}
}

return 0;
}

字符串哈希

给定一个长度为 n 的字符串,再给定 m 个询问,每个询问包含四个整数 l1,r1,l2,r2,请你判断 <l1,r1>< 和 <l2,r2> 这两个区间所包含的字符串子串是否完全相同。

字符串中只包含大小写英文字母和数字。

输入格式

第一行包含整数 n 和 m,表示字符串长度和询问次数。

第二行包含一个长度为 n 的字符串,字符串中只包含大小写英文字母和数字。

接下来 m 行,每行包含四个整数 l1,r1,l2,r2,表示一次询问所涉及的两个区间。

注意,字符串的位置从 11 开始编号。

输出格式

对于每个询问输出一个结果,如果两个字符串子串完全相同则输出 Yes,否则输出 No

每个结果占一行。

数据范围

1≤n,m≤1e5

输入样例:

1
2
3
4
5
8 3
aabbaabb
1 3 5 7
1 3 6 8
1 2 1 2

输出样例:

1
2
3
Yes
No
Yes

个人不会

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
#include<bits/stdc++.h>
using namespace std;
const int Q = 131;

typedef unsigned long long UII;
// 阴间结论 131 的基 和 2^64的模可以认为是不出现差错
const int N = 100100;
// 分别用来存储 p[i] = Q的i次方
// S[i] 从零开始 到达 i 所代表的字符串的数字
UII p[N],s[N];
UII getUII(int l, int r) {
UII rg = s[r];
UII lg = s[l-1];
// 对齐
lg *= p[r-l+1];
return rg - lg;
}

int main() {
int n,m;cin>>n>>m;
string c;
p[0] = 1;
cin>>c; c = " "+c;

for(int i=1;i<=n;i++){
s[i] = s[i-1] * Q + c[i];
p[i] = p[i-1] * Q;
}

while(m--){
int l1,l2,r1,r2;
scanf("%d %d %d %d",&l1,&r1,&l2,&r2);
if (getUII(l1,r1) == getUII(l2,r2)) {
cout<<"Yes"<<endl;
} else {
cout<<"No"<<endl;
}
}
}
/*
8 3
aabbaabb
1 3 5 7
1 3 6 8
1 2 1 2

*/