P3370 【模板】字符串哈希

首先这题不能用trie做,因为极限情况下,每一个字符串的长度最大1500,共10000个字符串,并且都不相同,那么大约需要的空间:
\(1 + 62 + 62 * 62 + ... + 62^{1499} = \frac{1 - 62^{1500}}{1 - 62}\approx 62^{1499} = 62^{1499} * 4 / 2048(MB)\)
这玩意是个2685位的天文数字,所以不行。

trie代码

#include<iostream>
using namespace std;

const int N = 300010;

int son[N][62], idx; // 0~9(10), a~z(26), A~Z
int cnt[N];
char str[N];
int n;
int res;

void insert(char str[]){
    int p = 0;
    for(int i = 0; str[i]; i ++){
        int x;
        if(str[i] >= 'A' && str[i] <= 'Z') x = str[i] - 'A' + 36;
        if(str[i] >= 'a' && str[i] <= 'z') x = str[i] - 'a' + 10;
        if(str[i] >= '0' && str[i] <= '9') x = str[i] - '0';
        if(son[p][x] == 0) son[p][x] = ++ idx;
        p = son[p][x];
    }
    cnt[p] ++;
    if(cnt[p] == 1) res ++;
}

int main(){
    cin >> n;
    
    while(n --){
        cin >> str;
        
        insert(str);
    }
    
    cout << res;
    
    return 0;
}

考虑字符串哈希,用前缀哈希法。

#include<iostream>
#include<algorithm>

using namespace std;

const int N = 10010, P = 131;

#define ULL unsigned long long

ULL a[N];
int n, k;
char str[N];

ULL get(char str[]){ // 将str作为131进制数,返回mod 2^64的值
    ULL res = 0;
    for(int i = 0; str[i]; i ++) res = res * P + str[i];
    return res;
} 

int main(){
    cin >> n;
    while(n --){
        cin >> str;
        
        a[k ++] = get(str);
    }
    
    sort(a, a + k);
    
    int cnt = 1;
    for(int i = 1; i < k; i ++)
        if(a[i - 1] != a[i]) cnt ++;
    
    cout << cnt;
    
    return 0;
}
posted @ 2020-10-26 10:48  yys_c  阅读(99)  评论(0编辑  收藏  举报