P2292 [HNOI2004]L language

Posted by leeperryar on Sat, 26 Oct 2019 17:00:59 +0200

Meaning: the first line has two integers n,m indicates that there are n words in the dictionary, and then M queries. Each line has a string indicating the article. For each piece of input article, you need to output the position of the longest prefix that the article can be understood in the dictionary.

Solution: consider building a dictionary tree, throwing the characters of the dictionary into it, and then consider asking. We can run a cycle first, find out where the article can match in the dictionary tree, and then search again where it can match from the marked place, and find the maximum value. See the code for specific details.

#include<bits/stdc++.h>
using namespace std;
const int MAXNODE = 1e6+50;
const int MAXSIZE = 26;
struct Trie{
    int nxt[MAXNODE][MAXSIZE],fail[MAXNODE],mark[MAXNODE];
    int vis[MAXNODE];
    int sz;
    void Insert(char *s){
        int root=0,len=strlen(s);
        for(int i=0;i<len;i++){
            int x = s[i]-'a';
            if(!nxt[root][x]) nxt[root][x] = ++sz;
            root = nxt[root][x];
        }
        mark[root] = 1;
    }
    int Query(char *s){
        int root=0,len=strlen(s),res=0;
        memset(vis,0,sizeof(vis));
        for(int i=0;i<len;i++){
            if(!nxt[root][s[i]-'a']) break;
            root = nxt[root][s[i]-'a'];
            if(mark[root]) vis[i] = 1;
        }//Search out the location that can be matched for the first time
        for(int i=0;i<len;i++){
            if(!vis[i]) continue;
            //If the local time matches the successful update answer, and matches again from the root node
            res=i+1,root=0;
            for(int j=i+1;j<len;j++){
                if(!nxt[root][s[j]-'a']) break;
                root = nxt[root][s[j]-'a'];
                if(mark[root]) vis[j]=1;
            }
        }
        return res;
    }
}automata;
int main(){
    int n,m;
    char str[MAXNODE];
    scanf("%d%d",&n,&m);
    for(int i=0;i<n;i++) scanf("%s",str),automata.Insert(str);
    for(int i=0;i<m;i++) scanf("%s",str),printf("%d\n",automata.Query(str));
    return 0;
}