HDU-3336 Count the string (KMP)

That Italy: T question, m is a string, then all the output matching prefix strings appear and the number of which is the mod 10007

Ideas: In the beginning you can think of using kmp statistics substring matching template number of occurrences (with a for loop to a match) but the string length (1 <= n <= 200000) so definitely go for a timeout, so we dp try to solve the (record some common information) we set dp [i] represents the string before i characters appear in any number prefix to the i-th character ending, next [i] is also the longest common prefixes and suffixes back distance. In fact this is the use of a portion of KMP (back to find the same prefix and suffix) for circulating the processing section;

Therefore Release dp [i] = dp [next [i]] + 1 such an equation (repeat matches can be reduced); (fallback character on a same tail)

Complete code:

#include <iostream>
#include <cstring>
#include <cmath>
#define mod 10007
using namespace std;
const int maxn = 2e5+9;
int dp[maxn],nex[maxn];
char s[maxn];
int len1,len2;
void getnext(){
    int i=0,j=-1;
    nex[i] = j;
    while(i<len1){
        if(j==-1||s[i]==s[j]){
            nex[++i] = ++j;
        }else{
            j = nex[j];
        }
    }
}

int main(){
    int T;
    scanf("%d",&T);
    while(T--){
        int sum = 0;
        scanf("%d",&len1);
        scanf("%s",&s);
        memset(dp,0,sizeof(dp));
        getnext(); 
        for(int i=1;i<=len1;i++){
            dp[i]=dp[nex[i]]+1;
            sum = (sum+dp[i])%mod;
        }
        printf("%d\n",sum);
    }
}

 

 

 

Start writing the code for loop TLE TLE remember :( not be repeated in the future issue of the string ...)

#include <iostream>
#include <cstring>
#include <cmath>
#define mod 10007
using namespace std;
const int maxn = 2e5+9;

int nex[maxn];
char s[maxn];
char s1[maxn];
int len1,len2;
void getnext(){
    int i=0,j=-1;
    nex[i] = j;
    while(i<len1){
        if(j==-1||s[i]==s[j]){
            nex[++i] = ++j;
        }else{
            j = nex[j];
        }
    }
}
int kmp_count(){
    int ans = 0;
    int i= 0,j=0;
    for(i=0;i<len1;i++)
    {
        while(j>0&&s[i]!=s1[j])
            j=nex[j];
        if(s[i]==s1[j])    j++;
        if(j==len2)
        {
            ans++;
            j=nex[j];
        }
    }
    return ans;
}
int main(){
    int T;
    cin>>T;
    while(T--){
        int ans = 0;
        scanf("%d",&len1);
        scanf("%s",&s);
        getnext(); 
        for(int i=0;i<len1;i++){
            len2 = i+1;
            s1[i]=s[i];
            ans = (ans + kmp_count())% mod ;
        }
        cout<<ans<<endl;
    }
}

 

Guess you like

Origin www.cnblogs.com/Tianwell/p/11240891.html