23.hash

作者: Tsukinousag | 来源:发表于2020-03-11 02:23 被阅读0次

    原题链接

    字符哈希串的意思:其实就是将字符串的前缀转换为数来存值
    由于每位的权值是不一样的 所以每个前缀值都对应着唯一的一种字符串

    所以相减后的值也应该是唯一的 从而利用相减后的值可以判断字符串的区间段是否相等

    注意点:

    • 由于前缀值的值会很大 所以应该将数组中的数据定义为ULL型
      typedef unsigned long long ULL;

    • P为权重,131为经验值 即P=131或13331时 哈希冲突的可能性最小

    • ULL h[N]; //h[]存放字符串的前缀值
      ULL p[N]; //p[]存放各个位数的相应权值

    • 将h[l-1]左移,其目的事实上是为了将h[l-1]的高位与h[r]的高位相对齐从而完成计算

    • p[0]的权值必须赋值为1 ,字符串下标必须从1开始

    再是计算公式:

    #include<bits/stdc++.h>
    #include<cstring>
    using namespace std;
    typedef unsigned long long ULL;
    
    const int N=1e5+10,P=131;
    char str[N];
    int n,m;
    ULL h[N],p[N];
    
    ULL get(int l,int r)
    {
        return h[r]-h[l-1]*p[r-l+1];
    }
    
    int main()
    {
        cin>>n>>m;
        scanf("%s",str+1);//字符串下标从1开始
        
        p[0]=1;//0的任何进制都是1
        
        for(int i=1;i<=n;i++)//求出字符串长度的所有hash值
        {
            p[i]=p[i-1]*P;//每一位所表示的进制
            h[i]=h[i-1]*P+str[i];//每一位的hash值
        }
        while(m--)
        {
            int l1,r1,l2,r2;
            scanf("%d%d%d%d",&l1,&r1,&l2,&r2);
            if(get(l1,r1)==get(l2,r2))
            {
                cout<<"Yes"<<endl;
            }
            else
                cout<<"No"<<endl;
        }
        return 0;
    }
    

    相关文章

      网友评论

          本文标题:23.hash

          本文链接:https://www.haomeiwen.com/subject/yhbadhtx.html