维护一个集合,支持如下几种操作:
- “I x”,插入一个数x;
- “Q x”,询问数x是否在集合中出现过;
现在要进行N次操作,对于每个询问操作输出对应的结果。
输入格式
第一行包含整数N,表示操作数量。
接下来N行,每行包含一个操作指令,操作指令为”I x”,”Q x”中的一种。
输出格式
对于每个询问指令“Q x”,输出一个询问结果,如果x在集合中出现过,则输出“Yes”,否则输出“No”。
每个结果占一行。
数据范围
1 ≤ N ≤ 10^5
−10^9 ≤ x ≤ 10^9
输入样例
输出样例
模板
开放寻址法
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 <iostream> #include <cstring>
using namespace std;
const int N = 200003, null = 0x3f3f3f3f;
int n; int h[N];
int find(int x) { int k = (x % N + N) % N; while(h[k] != null && h[k] != x) { k ++; if(k == N) k = 0; } return k; }
int main() { scanf("%d", &n); memset(h, 0x3f, sizeof h); while(n --) { char op[2]; int x; scanf("%s%d", op, &x); int k = find(x); if(op[0] == 'I') h[k] = x; else { if(h[k] == x) puts("Yes"); else puts("No"); } } 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
| #include <iostream> #include <cstring>
using namespace std;
const int N = 100003;
int n; 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() { scanf("%d", &n); memset(h, -1, sizeof(h)); while(n --) { char op[2]; int x; scanf("%s%d", op, &x); if(op[0] == 'I') insert(x); else { if(find(x)) puts("Yes"); else puts("No"); } } return 0; }
|