Zoj 3587 Marlon's string (Extended KMP + dp)

Source: Internet
Author: User

Link:

Http://acm.zju.edu.cn/onlinejudge/showProblem.do? Problemcode = 3587.

Question:

For the string S, T, find all the rad (A, B, C, D), Sa... B + SC... d = t, a ≤ B and c ≤ d.

In fact, t is divided into two segments, both of which are composed of substrings in S, and the number of combinations is required (the two substrings in S can overlap ).

Analysis and Summary:

The AC of this question is one of my most happy ones in recent days, because the DP question is still rarely done with some basic models and has a sense of fear for DP, this question uses the DP idea, and the results are confused ......

My ideas:

If t is set to Len, t can have a prefix of T1 and a suffix of T2.

According to the length of the classification, T1 length can be 1, 2, 3... len-1, the length of the corresponding T2 can also be 1, 2, 3... len-1.

Suppose there is a T1 with the length of X. to piece together the complete T, we need to find a suffix T2 with the length of len-X.

Then, in S, there are substrings T1, T2, cnt1 [I] indicating the number of T1 with the length of I. Similarly, cnt2 [I] indicates the number of T2 with the length of I, all the patchwork schemes are sum = cnt1 [1] * cnt2 [len-1] + cnt1 [2] * cnt2 [len-2] + .... CNT [len-1] * CNT [1].


After understanding the above conclusions, the key is to calculate the number of matching strings T1 and T2 with various lengths in S.

My method is to use the extended KMP to find the longest common substring length of all Suffixes in s with the T prefix, extend [I] indicates the longest Public String starting with s [I] with the T prefix. Based on these lengths, you can determine the number of T1. Suppose S = "aabcde", t = "abcge", then extend [0] = 1, extend [1] = 3...

Then, find the suffix T2. You can transpose all S and T, and store them in reverse order. Then, use the same method to find the number of T2.


However, the extend array is not enough. We need to find the number of T1 and T2 of all lengths. This step uses the DP idea.

We can know:

When extend [I] = 2, this 2 also contains a string of 1.

When extend [I] = 3, this 3 also contains the string of 2, 1.

When extend [I] = 4, this 4 also contains 3, 2, 1 strings.

When extend [I] = 5, this 5 also contains a string of 4, 3, 2, 1.

...

Therefore, put the number of extends directly in CNT, and then calculate it like this (I don't know how to describe it, just put the code ):

       for(int i=0; S[i]; ++i){            if(extend1[i]){                ++cnt1[extend1[i]];            }            if(extend2[i]){                ++cnt2[extend2[i]];            }        }        for(int i=len-1; i>=1; --i){            cnt1[i] += cnt1[i+1];            cnt2[i] += cnt2[i+1];        }


Then, you can calculate the answer based on the formula.

Code:

#include<iostream>#include<cstdio>#include<cstring>using namespace std;typedef long long int64; const int MAXN = 200005;char S[MAXN];char T[MAXN];int  f[MAXN];int64  cnt1[MAXN], cnt2[MAXN];int  extend1[MAXN], extend2[MAXN];void getNext(char* T,int* next){    int len=strlen(T), a=0;    next[0] = len;    while(a<len-1 && T[a]==T[a+1])++a;    next[1] = a;    a=1;    for(int k=2; k<len; ++k){        int p=a+next[a]-1, L=next[k-a];        if(k-1+L >= p){            int j=max(p-k+1,0);            while(k+j<len && T[k+j]==T[j]) ++j;            next[k] = j;            a=k;        }        else             next[k] = L;    }}void EKMP(char* S,char* T,int* next, int* extend){    getNext(T,next);    int slen=strlen(S), tlen=strlen(T), a=0;    int minlen=min(slen,tlen);    while(a<minlen && S[a]==T[a])++a;    extend[0] = a;    a=0;    for(int k=1; k<slen; ++k){        int p=a+extend[a]-1, L=next[k-a];        if(k-1+L >= p){            int j=max(p-k+1,0);            while(k+j<slen && j<tlen && S[k+j]==T[j]) ++j;            extend[k] = j;            a=k;        }        else            extend[k] = L;    }}int main(){    int nCase;    scanf("%d",&nCase);    while(nCase--){        memset(S, 0, sizeof(S));        memset(T, 0, sizeof(T));        scanf("%s %s",S,T);        EKMP(S,T,f,extend1);        int len=strlen(S);        for(int i=0,k=len-1; i<len/2; ++i,--k){            char ch=S[i];            S[i] = S[k];            S[k] = ch;        }        len=strlen(T);        for(int i=0, k=len-1; i<len/2; ++i,--k){            char ch=T[i];            T[i] = T[k];            T[k] = ch;        }        EKMP(S,T,f,extend2);        memset(cnt1, 0, sizeof(cnt1));        memset(cnt2, 0, sizeof(cnt2));        for(int i=0; S[i]; ++i){            if(extend1[i]){                ++cnt1[extend1[i]];            }            if(extend2[i]){                ++cnt2[extend2[i]];            }        }        for(int i=len-1; i>=1; --i){            cnt1[i] += cnt1[i+1];            cnt2[i] += cnt2[i+1];        }                long long ans=0;        for(int i=1; i<len; ++i)            ans += cnt1[i] * cnt2[len-i];        printf("%lld\n",ans);    }    return 0;}


 -- The significance of life is to give it a meaningful person.

Original Http://blog.csdn.net/shuangde800,
D_double (reprinted please mark)

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.