zoukankan      html  css  js  c++  java
  • 哈希与字典树与KMP

      hash讲解

      主要记录hash的公式:

    for (int i=1; i<=len; i++) {
            Hash[i]=(Hash[i-1]*base%mod+(s[i]-'A'+1)%mod)%mod;
        }

      求hash的公式是这个,怎么求一小段的hash值呢?

    for (int i=1; i<=len; i++) {
            p[i]=p[i-1]*base%mod;
        }

    ll get(int l, int r) {
      return (Hash[r]%mod-Hash[l-1]*p[r-l+1]%mod)%mod;
    }

      我一直不理解为什么要乘p[r-l+1]呢?现在明白啦*★,°*:.☆( ̄▽ ̄)/$:*.°★* 。

      首先给你一个字符串abcdef,hash[6]=a*p^5+b*p^4+c*p^3+d*p^2+e*p^1+f*p^0。如果我们要求def的hash值怎么求呢?

      我们知道hash[6]=a*p^5+b*p^4+c*p^3+d*p^2+e*p^1+f*p^0,hash[3]=a*p^2+b*p^1+c*p^0。

      而def的hash值是d*p^2+e*p^1+f*p^0,那么就看得出def的hash值是(Hash[r]%mod-Hash[l-1]*p[r-l+1]%mod)%mod这个公式。

      板子:

    /*  gyt
           Live up to every day            */
    #include<cstdio>
    #include<cmath>
    #include<iostream>
    #include<algorithm>
    #include<vector>
    #include<stack>
    #include<cstring>
    #include<queue>
    #include<set>
    #include<string>
    #include<map>
    #include <time.h>
    #define PI acos(-1)
    using namespace std;
    typedef long long ll;
    typedef double db;
    const int maxn = 4e4+10;
    const ll maxm = 1e7;
    const int mod = 1e9+7;
    const int INF = 1<<30;
    const db eps = 1e-9;
    const ll base = 1e9+13;
    ll Hash[maxn];
    ll p[maxn];
    char s1[maxn], s2[maxn];
    
    void init(char *s) {
        p[0]=1;
        Hash[0]=0;
        int len=strlen(s+1);
        for (int i=1; i<=len; i++) {
            p[i]=p[i-1]*base%mod;
        }
        for (int i=1; i<=len; i++) {
            Hash[i]=(Hash[i-1]*base%mod+(s[i]-'A'+1)%mod)%mod;
        }
    }
    ll get(int l, int r) {
        return (Hash[r]%mod-Hash[l-1]*p[r-l+1]%mod)%mod;
    }
    void solve() {
        while(scanf("%s", s2+1)!=EOF) {
            if (s2[1]=='#')  break;
            scanf("%s", s1);
            int len1=strlen(s1);
            int len2=strlen(s2+1);
            int num=0, biao=0;
            init(s2);
            ll haha=0;
            for (int i=0; i<len1; i++) {
                haha = (haha*base%mod+(s1[i]-'A'+1)%mod)%mod;
            }
            int ans=0;
            for (int i=1; i+len1-1<=len2; i+=len1) {
                ll ha=get(i, i+len1-1);
                if (ha==haha)  ans++;
            }
            printf("%d
    ", ans);
        }
    }
    int main() {
        int t = 1;
       // freopen("in.txt", "r", stdin);
        //scanf("%d", &t);
        while(t--)
            solve();
        return 0;
    }

       字典树板子

      

    /*  gyt
           Live up to every day            */
    #include<cstdio>
    #include<cmath>
    #include<iostream>
    #include<algorithm>
    #include<vector>
    #include<stack>
    #include<cstring>
    #include<queue>
    #include<set>
    #include<string>
    #include<map>
    #include <time.h>
    #define PI acos(-1)
    using namespace std;
    typedef long long ll;
    typedef double db;
    const int maxn = 4e4+10;
    const ll maxm = 1e7;
    const int modd = 10000007;
    const int INF = 1<<30;
    const db eps = 1e-9;
    struct Trie{
        int v;
        Trie *next[26];
    };
    Trie root;
    
    void creat(char *str) {
        int len=strlen(str);
        Trie *p=&root, *q;
        for (int i=0; i<len; i++) {
            int id=str[i]-'a';
            if (p->next[id]==NULL) {
                q=(Trie *)malloc(sizeof(root));
                q->v=1;
                for (int j=0; j<26; j++)
                    q->next[j]=NULL;
                p->next[id]=q;
                p=p->next[id];
            }
            else {
                p->next[id]->v++;
                p=p->next[id];
            }
        }
    }
    int Find(char *str) {
        int len=strlen(str);
        Trie *p=&root;
        for (int i=0; i<len; i++) {
            int id=str[i]-'a';
            p=p->next[id];
            if (p==NULL)  return 0;
        }
        return p->v;
    }
    void solve() {
        char str[100];
        for (int i=0; i<26; i++)
            root.next[i]=NULL;
        while(gets(str)) {
            if (str[0]=='')  break;
            creat(str);
        }
        while(gets(str)) {
            if (str[0]=='')  break;
            int ans=Find(str);
            printf("%d
    ", ans);
        }
    }
    int main() {
        int t = 1;
       // freopen("in.txt", "r", stdin);
        scanf("%d", &t);
        while(t--)
            solve();
        return 0;
    }
  • 相关阅读:
    决定你人生高度的,不是你的才能,而是你的态度
    享受六一的最后几分钟
    DB9 公头母头引脚定义及连接
    bzoj3207--Hash+主席树
    bzoj1901 [ Zju2112 ] --树状数组套主席树
    bzoj1723 [ Usaco2009 Feb ] --前缀和(水题)
    bzoj3932 [ CQOI2015 ] --可持久化线段树
    bzoj3037--贪心
    bzoj3388 [ Usaco2004 Dec ] (神奇的解法)
    bzoj2693--莫比乌斯反演+积性函数线性筛
  • 原文地址:https://www.cnblogs.com/gggyt/p/7209709.html
Copyright © 2011-2022 走看看