[BZOJ 2061] Country (KMP + memory search)

[BZOJ 2061] Country (KMP + memory search)

Face questions

gaoxin Ben frequent manifestation of God's love of the great, glorious and correct xx in his statement, we can make the following definition: A = the great, glorious and correct B = xx C = lead us forward praise of the motherland = ABC desperately praise of the motherland = praise of the motherland speak 10 gaoxin desperately praise of the motherland = 100 obviously, this definition must be acyclic. WJMZBMR feel very stressful, he managed to count the number of occurrences of a string. . .

One day he turned on the TV and found someone's speech has the same structure. . He was speechless. . . Want to know the number of times certain strings appear. . Can you help him?

Some definitions: In order to simplify the period, represented by the English input.

String: lowercase letters such as a

String name: it must be uppercase letters such as A then the above system can be written as A = greatglorycorrect B xx C leadusgo D = ABC E = DDDDdjh F = EEEEEgoodbye there is a female name string at the same time, he is someone to speak = =

analysis

Memory search, \ (DP [I] [J] \) represents the current process to the string \ (I \) (not yet matched i), the previous string matching template to \ (J \) matches the number of bits when .

We traverse i for each character, if it is lowercase, on the use of KMP match, and has now recorded matched to the position x. If capital letters id, recursively dfs (id, x). To update the matching position, we have to maintain an additional array \ (pos [i] [j ] \) indicates that the current process to the string \ (i \) (not yet match i), the last string matching template to \ (j \) after the end of the bit string matching template location. After completion of the recursively assigned to x \ (POS [ID] [x] \) . Also update \ (DP [I] [J] \) . After each traverse the character \ (pos [i] [j ] \ ) assigned to x

The final answer is \ (dp [S] [0] \) (which is why we define j indicates a match when the initial position, or else we do not know where the last match)

Code

#include<iostream>
#include<cstdio>
#include<cstring>
#include<vector>
#include<algorithm>
#include<cctype>
#include<queue>
#define maxn 26
#define maxl 100000
#define mod 10000

using namespace std;
int n,s;


inline bool isAlpha(char c){
    return c>='A'&&c<='Z';
}
void get_nex(char *s,int n,int *nex) {
    nex[1]=0;
    for(int i=2,j=0; i<=n; i++) {
        while(j&&s[j+1]!=s[i]) j=nex[j];
        if(s[j+1]==s[i]) j++;
        nex[i]=j;
    }
}

int a[maxn+5][maxl+5];
int len[maxn+5];
char tp[maxn+5],lentp;
int nex[maxl+5];

int dp[maxn+5][maxl+5];
//dp[i][j]表示字符串i,当前还未匹配时末尾已经与模板串匹配了j位,
//串i里包含模板串的个数 
int pos[maxn+5][maxl+5];//pos[i][j]表示匹配结束后KMP指针的位置 
int dfs(int i,int j){
    if(dp[i][j]!=-1) return dp[i][j];
    dp[i][j]=0;
    int x=j;
    for(int k=1;k<=len[i];k++){
        if(isAlpha(a[i][k])){
            int id=a[i][k]-'A'+1;
            dp[i][j]+=dfs(id,x);
            dp[i][j]%=mod;
            x=pos[id][x]; 
        }else{
            int p=x;
            while(p&&tp[p+1]!=a[i][k]) p=nex[p];
            if(tp[p+1]==a[i][k]) p++;
            x=p;
            if(x==lentp){
                dp[i][j]++;
                dp[i][j]%=mod;
            } 
        }
    }
    pos[i][j]=x;
    return dp[i][j];
}

char in[maxl+5];
int main() {
    scanf("%d",&n);
    scanf("%s",in+1);
    s=in[1]-'A'+1;
    for(int i=1; i<=n; i++) {
        scanf("%s",in+1);
        int l=strlen(in+1);
        for(int j=3; j<=l; j++) a[in[1]-'A'+1][j-2]=in[j];
        len[i]=l-2;
    }
    scanf("%s",tp+1);
    lentp=strlen(tp+1); 
    get_nex(tp,lentp,nex);
    memset(dp,0xff,sizeof(dp));
    dfs(s,0); 
    printf("%d\n",dp[s][0]);
}

Guess you like

Origin www.cnblogs.com/birchtree/p/12172306.html