One string training

String training

Example a

https://www.luogu.org/problem/P2292

Gives the N word, and M sentences, the longest prefix ask each sentence contained in these words is.

Problem-solving skills :

Extracting keywords : prefix sentence ...... .....

Good learned AC automaton of you should know

But now there is a requirement longest

Is a maximum problem:? Dp greedy?

The only way to insert other operations in the automatic machine ac only an array of queries fail when the job

In this case the problem has been resolved more than half the

The core came

for(int y=x;y;y=fail[y])
            if(is_end[y]&&exi[p+1-dep[y]]){
                exi[p+1]=1;
                break;
            }

Carefully think about it seems to have found the truth

Why should we break out

Since then fail to find in the only growing worse

If this is not understood to go back and re-learn it Automata

code:

#include<iostream>
#include<cstring>
#include<cstdio>
#include<queue>
using namespace std;
const int N=20+5;
const int L=10+5;
const int M=0x100010;
template<class T>inline void read(T &num){
    char ch;
    while(!isdigit(ch=getchar()));
    num=ch-'0';
    while(isdigit(ch=getchar()))num=num*10+ch-'0';
}
int tri[N*L][26],dep[N*L],fail[N*L],is_end[N*L],totn,n,m;
int exi[M];
char str[M];
inline void Insert(char s[]){
    int x=0,len=strlen(s);
    for(int p=0;p<len;++p){
        int ch=s[p]-'a';
        if(tri[x][ch]==0){
            tri[x][ch]=++totn;
            dep[totn]=dep[x]+1;
        }
        x=tri[x][ch];
    }
    is_end[x]=1;
}

queue<int> que;
void Fail(){
    int x=0;
    for(int i=0;i<26;++i)if(tri[x][i])que.push(tri[x][i]);
    while(que.size()){
        x=que.front();que.pop();
        for(int i=0;i<26;++i){
            if(tri[x][i])fail[tri[x][i]]=tri[fail[x]][i],que.push(tri[x][i]);
            else tri[x][i]=tri[fail[x]][i];
        }
    }
}

int AC(char str[]){
    memset(exi,0,sizeof(exi));
    exi[0]=1;
    int x=0,len=strlen(str);
    for(int p=0;p<len;++p){
        int ch=str[p]-'a';
        x=tri[x][ch];
        for(int y=x;y;y=fail[y]){
            if(is_end[y]&&exi[p+1-dep[y]]){
                exi[p+1]=1;
                break;
            }
        }
    }
    for(int i=len;i;--i)if(exi[i])return i;
    return 0;
}

int main(){
    read(n),read(m);
    for(int i=1;i<=n;++i){
        scanf("%s",str);
        Insert(str);
    }
    Fail(); 
    for(int i=1;i<=m;++i){
        scanf("%s",str);
        printf("%d\n",AC(str));
    }
    return 0;
}

Guess you like

Origin www.cnblogs.com/wzxbeliever/p/11609369.html