2021-01-26

hash表
散列hash
散列函数选择 h(x) = x mod k 时
拉链法:k一般选择质数较好
开放寻址法:散列表长度一般开数据范围的2~3倍,保证查询时不会因表被装满导致死循环
开放寻址法

#include <iostream>
#include <cstring>
using namespace std;

const int N = 2e5 + 3, null = 0x3f3f3f3f;

int h[N], n, x;
char op;

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() {
    cin >> n;
    memset(h, null, sizeof h);
    while (n--) {
        cin >> op >> x;
        if (op == 'I') {
            h[find(x)] = x;
        } else if (op == 'Q') {
            if (h[find(x)] == x) cout << "Yes" << endl;
            else cout << "No" << endl;
        }
    }
    return 0;
}

拉链法

#include <iostream>
#include <cstring>
using namespace std;

const int N = 1e5 + 3;

// 链表存储映射地址相同的结点
int h[N], e[N], ne[N], idx;
int n, x;
char op;

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

bool query(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() {
    cin >> n;
    memset(h, -1, sizeof h);
    while (n--) {
        cin >> op >> x;
        if (op == 'I') {
            insert(x);
        } else if (op == 'Q') {
            if (query(x)) cout << "Yes" << endl;
            else cout << "No" << endl;
        }
    }
    return 0;
}

字符串hash
h[i]表示字符串前i个字符组成的前缀的哈希值
p[i]=Pip[i]=Pi,提前算好方便之后计算
PP一般取131或者13331,哈希冲突概率最小
类型取unsigned long long, 等价于模2^64
计算字串S[l:r]的哈希值公式:h[l:r]=(h[r]−h[l−1]∗Pr−l+1)%Q,Q=264h[l:r]=(h[r]−h[l−1]∗Pr−l+1)%Q,Q=264

#include <iostream>
using namespace std;

typedef unsigned long long ULL;

const int N = 1e5 + 10, P = 131;

int h[N], p[N], n, m;
char s[N];

int get(int l, int r) {
    return h[r] - h[l - 1] * p[r - l + 1];
}

int main() {
    cin >> n >> m >> s + 1;
    p[0] = 1;
    for (int i = 1; i <= n; i ++ ) {
        p[i] = p[i - 1] * P;
        h[i] = h[i - 1] * P + s[i];
    }
    int l1, l2, r1, r2;
    while (m -- ) {
        cin >> l1 >> r1 >> l2 >> r2;
        if (get(l1, r1) == get(l2, r2)) cout << "Yes" << endl;
        else cout << "No" << endl;
    }
    return 0;
}


已标记关键词 清除标记
相关推荐
©️2020 CSDN 皮肤主题: 游动-白 设计师:白松林 返回首页