白兔的字符串(hash)

https://ac.nowcoder.com/acm/problem/15253

#include<bits/stdc++.h>

using namespace std;
# define ull unsigned long long
const int mod = 1e9 + 7;
const int maxn = 1e6 + 100;
const int mod_map = 14937;
char str1[maxn], str2[maxn];
ull p[maxn], hash1[maxn], hash2[maxn];

struct node {
    ull to;
    int nex;
} edge[maxn];
int head[maxn], cnt;

void addedge(ull x) {
    int pos = x % mod_map;
    edge[cnt].to = x;
    edge[cnt].nex = head[pos];
    head[pos] = cnt++;
}

int Find(ull x) {
    int pos = x % mod_map;
    for (int i = head[pos]; i != -1; i = edge[i].nex) {
        if (edge[i].to == x)
            return 1;
    }
    return 0;
}

ull get_sub1(int l, int r) {
    return hash1[r] - hash1[l - 1] * p[r - l + 1];
}

ull get_sub2(int l, int r) {
    return hash2[r] - hash2[l - 1] * p[r - l + 1];
}

void init2() {
    int len = strlen(str1 + 1);
    for (int i = len + 1; i <= len + len; i++)
        str1[i] = str1[i - len];
    for (int i = 1; i <= len + len; i++) {
        hash1[i] = hash1[i - 1] * 131 + (ull) (str1[i]);
        if (i >= len) {
            ull tmp = get_sub1(i - len + 1, i);
            addedge(tmp);
        }
    }
}

int main() {
    //freopen("in", "r", stdin);
    memset(head, -1, sizeof(head));
    p[0] = 1;
    for (int i = 1; i < maxn; i++)
        p[i] = p[i - 1] * 131;
    scanf("%s", str1 + 1);
    int len1 = strlen(str1 + 1);
    init2();
    int T;
    scanf("%d", &T);
    while (T--) {
        int ans = 0;
        scanf("%s", str2 + 1);
        int len2 = strlen(str2 + 1);
        for (int i = 1; i <= len2; i++) {
            hash2[i] = hash2[i - 1] * 131 + (ull) (str2[i]);
            if (i >= len1)
                if (Find(get_sub2(i - len1 + 1, i)))
                    ans++;
        }
        printf("%d\n", ans);
    }
    return 0;
}
View Code

猜你喜欢

转载自www.cnblogs.com/xcfxcf/p/12397082.html