HDU3336——KMP算法

题意是问所有前缀出现的次数和,mod10007;

想一想next数组代表什么意思,是从当前失配位置走到上一个匹配位置的后面,next[i]的值说明以当前位置为结尾,长度为next[i]的后缀,与以开头元素为起始,长度为next【i】

的前缀是相同的,那么方法就很容易了,对于每个j = i,沿着next【j】往前走,到0为止,记录走过的次数,就是前缀的出现次数。

#include<cstdio>
#include<algorithm>
#include<cstring>
#include<iostream>
#include<map>
#include<vector>
#include<cmath>
#include<set>
using namespace std;
const int maxn = 1e6+5;
const int mod = 10007;
char s[maxn];

vector<int> find_sub(char *pattern)//预处理next
{
    int n = strlen(pattern);
    vector<int> next(n+1,0);
    for(int i = 1; i < n; ++i)
    {
        int j = i;
        while(j > 0){
            j = next[j];
            if(pattern[j] == pattern[i]){

                next[i+1] = j+1;
                break;
            }
        }
    }
    return next;
}

int main()
{
   // freopen("in","r",stdin);
    int T;
    scanf("%d",&T);
    while(T--)
    {
        int n;
        scanf("%d",&n);
        scanf("%s",s);
        vector<int> v = find_sub(s);
        int ans = 0;

for(int i = 0; i < v.size(); ++i) { int j = i; while(j){ ans = (ans+1)%mod; j = v[j]; } } printf("%d\n",ans); } }

 

posted @ 2015-08-26 10:27  Norlan  阅读(305)  评论(0编辑  收藏  举报