人生的第一次hash交给了模板题。
讲道理,还没有别人快排要快,就比暴力快那么一点。。。
难道我写的hash就那么菜么?
我想了想,光是处理字符串就O(n*len)。。
这是hash的正确写法吗?我都开始怀疑自己了。
不管怎样,把代码附上,以后可能会用。
#include <cstdio>
#include <cstring>
#include <iostream>
#include <cmath> using namespace std; int n;
string h[], s; const int mod = ; long long hash()
{
int i, len = s.length() - ;
long long ans = ;
for(i = ; i <= len; i++) ans = ans * + s[i] - 'a';
ans = abs(ans);
ans %= mod;
return ans;
} bool insert()
{
long long i = hash();
while(h[i] != s && h[i] != "") i++;
if(h[i] == s) return ;
h[i] = s;
return ;
} int main()
{
int i, j, ans = ;
scanf("%d", &n);
getline(cin, s);
for(i = ; i <= n; i++)
{
getline(cin, s);
if(insert()) ans++;
}
printf("%d", ans);
return ;
}
学习了别人的写法,200ms,感觉这才是正确姿势。
原来的我还是太naive了。
#include <cstdio>
#include <cstring>
#define ULL unsigned long long const int MAXN = , p = ;
int n, ans, cnt;
int head[MAXN], next[MAXN];
ULL val[MAXN];
char s[MAXN]; inline bool insert(ULL x)
{
int i, a = x % p;
for(i = head[a]; i != -; i = next[i])
if(val[i] == x)
return ;
val[cnt] = x;
next[cnt] = head[a];
head[a] = cnt++;
return ;
} inline void ha()
{
int i, len = strlen(s);
ULL hash = ;
for(i = ; i < len; i++) hash = hash * + s[i];
ans += insert(hash);
} int main()
{
int i;
memset(head, -, sizeof(head));
scanf("%d", &n);
while(n--)
{
scanf("%s", s);
ha();
}
printf("%d", ans);
return ;
}