【KMP】ZOJ 3587

利用了kmp的性质,kmp可以找出前i个在主串出现的次数(可覆盖),同样也可以找出后j个在主串出现的次数,只需要反向kmp就行了==,具体实现是两次预处理正向&反向,然后记录num1和num2数组

所以复杂度是线性时间.....理解kmp是重点!

#define N 100005
char s[N],t[N];
int next1[N],next2[N];
int num1[N],num2[N];//记录i左边在主串出现次数和i右边的
int l1,l2;
void gao1(){
    int i,j=-1;
    next1[0] = -1;
    for(i=1;i=0 && t[i]!=t[j+1]){
            j = next1[j];
        }
        if(t[i]==t[j+1])j++;
        next1[i] = j;
    }
}
void gao2(){
    int i,j = l2;
    next2[l2-1] = l2;
    for(i=l2-2;i>=0;i--){
        while(j=0;i--){
        if(num1[i]){
            if(next1[i]!=-1){
                num1[next1[i]]+=num1[i];
            }
        }
    }
    ///
    j = l2;
    for(i=l1-1;i>=0;){
        if(s[i]==t[j-1]){
            num2[j-1]++;
            i--,j--;
        } else {
            if(j!=l2){
                j = next2[j];
            } else i--;
        }
    }
    for(i=0;i



















你可能感兴趣的:(字符串)