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]=='