Wannafly挑战赛11 D 题 字符串hash + 卡常

题目链接

https://ac.nowcoder.com/acm/contest/73#question

map与order_map

https://blog.csdn.net/BillCYJ/article/details/78985895

解析 先把T串的所有状态的hash值存在order_map里面  然后对于每一个模式串计算其每一个长度为len(T)的子串的hash值 若在order_map里面则ans++

        这道题1e7的数据查找比较多map(O(log(n)) 查找会比 order_map( O(1) )慢 然后再卡卡常就可以了。。。正解是ex_kmp

AC代码

#include<bits/stdc++.h>
using namespace std;
typedef unsigned long long ull;
const int maxn=2e6+10;
const int base=13331; //base,基数
 
char s1[maxn],s2[maxn];
ull Hash[maxn],temp[maxn],power=1; //记录主串哈希值的数组
 
int main()
{
    scanf("%s",s1+1); //从第一位开始输入
    int n=strlen(s1+1);
    Hash[0]=0;
    for(int i=1;i<=n;i++)
    {
        s1[i+n]=s1[i];
        power*=base;
        Hash[i]=Hash[i-1]*base+(ull)s1[i];
    }
    unordered_map<ull,int> ma;
    for(int i=n+1;i<=n+n;i++)
    {
        Hash[i]=Hash[i-1]*base+(ull)s1[i];
        ma[Hash[i]-Hash[i-n]*power]=1;
    }
    int k;
    scanf("%d",&k);
    while(k--)
    {
        int ans=0;
        scanf("%s",s2+1);
        int m=strlen(s2+1);
        if(m<n)
        {
            printf("0\n");
            continue;
        }
        temp[0]=0;
        for(int i=1;i<=m;i++)
        {
            temp[i]=temp[i-1]*base+(ull)s2[i];
            if(i>=n&&ma[temp[i]-temp[i-n]*power])
                ans++;
        }
        printf("%d\n",ans);
    }
    return 0;
}

 

posted @ 2019-02-24 15:29  灬从此以后灬  阅读(192)  评论(0编辑  收藏  举报