哈希(Hash)算法,即散列函數。它是一種單向密碼體制,即它是一個從明文到密文的不可逆的映射,只有加密過程,沒有解密過程。同時,哈希函數可以將任意長度的輸入經過變化以後得到固定長度的輸出。哈希函數的這種單向特徵和輸出數據長度固定的特徵使得它可以生成消息或者數據。
純裸的模板題
因爲要使字符串的哈希值各不相同,所以要取一些奇奇怪怪的質數進行MOD,比如19260817(逃)
常見的質數
爲了防止相同,經常會使用雙膜數,即取兩次模,判斷是否相等,就能使運算更加精確。
剛剛知道有一種操作,unsigned long long 可以溢出自動取模,所以如果不刻意去卡的話,可以用unsigned long long去做。
//hash
#include <bits/stdc++.h>
#define MOD1 19260817
#define MOD2 19660813
#define base 133
using namespace std;
char s[1000000];
struct H{
int one,two;
}hs[10001];
int hash1(char s[])
{
int len=strlen(s);
int ans=0;
for(int i=0;i<len;i++)
{
ans=(ans*base+(int)s[i])%MOD1;
}
return ans;
}
int hash2(char s[])
{
int len=strlen(s);
int ans=0;
for(int i=0;i<len;i++)
{
ans=(ans*base+(int)s[i])%MOD2;
}
return ans;
}
int comp(H a,H b)
{
return a.one<b.one;
}
int main()
{
int n;
cin>>n;
for(int i=1;i<=n;i++)
{
scanf("%s",s);
hs[i].one=hash1(s);
hs[i].two=hash2(s);
}
int ans=1;
sort(hs+1,hs+n+1,comp);
for(int i=2;i<=n;i++)
if(hs[i].one!=hs[i-1].one||hs[i].two!=hs[i-1].two)
ans++;
cout<<ans<<endl;
return 0;
}