字符串哈希前缀和
ULL get(int l, int r) { return h[r] - h[l - 1] * p[r - l + 1]; } int main() { cin >> n >> m >> str + 1; p[0] = 1; for(int i = 1; i <= n; i ++ ){ p[i] = p[i - 1] * P; h[i] = h[i - 1] * P + str[i]; }
普通哈希
#include <bits/stdc++.h> using namespace std; typedef long long ll; const int mod=5009; struct p{ int to,nxt; }d[50009];int head[50009],cnt=1; bool add(int x) { int now=(x%mod+mod)%mod; for(int i=head[now];i;i=d[i].nxt) if(d[i].to==x) return false; d[cnt].to=x,d[cnt].nxt=head[now]; head[now]=cnt++; return true; } int main() { int t,n; cin>>t; while(t--) { cin>>n; cnt=1; memset(d,0,sizeof(d));memset(head,0,sizeof(head)); for(int i=1;i<=n;i++) { int x;scanf("%d",&x); if(add(x)) printf("%d ",x); } cout<<endl; } return 0; }
字符串哈希
溢出哈希
#include <bits/stdc++.h> using namespace std; typedef unsigned long long ull; ull base=131;//131进制 ull a[10010];//hash后的数组 int n,ans=1; ull hashs(string s) { int l=s.length(); ull he=0; for(int i=0;i<l;i++) ans=ans*base+(ull)s[i];//溢出相当于取模 return ans&0x7fffffff; } int main() { scanf("%d",&n); string s; for(int i=1;i<=n;i++) { cin>>s; a[i]=hashs(s); } sort(a+1,a+1+n); for(int i=2;i<=n;i++) if(a[i]!=a[i-1]) ans++; cout<<ans; }
双模数哈希
#include <cstdio> #include <cstring> #include <algorithm> using namespace std; typedef unsigned long long ull; ull base=131; struct data { ull x,y; }a[10010]; char s[10010]; int n,ans=1; ull mod1=19260817; ull mod2=19660813; ull hash1(char s[]) { int len=strlen(s); ull ans=0; for (int i=0;i<len;i++) ans=(ans*base+(ull)s[i])%mod1; return ans; } ull hash2(char s[]) { int len=strlen(s); ull ans=0; for (int i=0;i<len;i++) ans=(ans*base+(ull)s[i])%mod2; return ans; } bool comp(data a,data b) { return a.x<b.x; } main() { scanf("%d",&n); for (int i=1;i<=n;i++) { scanf("%s",s); a[i].x=hash1(s); a[i].y=hash2(s); } sort(a+1,a+n+1,comp); for (int i=2;i<=n;i++) if (a[i].x!=a[i-1].x || a[i-1].y!=a[i].y) ans++; printf("%d ",ans); }