哈希表(模拟散列表&&字符串哈希)

一、模拟散列表(两种方法)

邻接表
数组(开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;
}```

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值