FZU 2108(AC自动机)

来源:互联网 发布:算法和程序的关系 编辑:程序博客网 时间:2024/06/02 00:03

fzu2108/ xmut1180

Description

给定一个字符串S,问S的子串中不包含A1,A2...AN的最长子串有多长。

Input

第一行为字符串S,字符串S的长度为B( 1 <= B <= 100000 ),第二行是不能包含的子串个数N( 1 <= N<= 1000 )。接下来N行字符串,每个字符串长度不超过C( 1 <= C <= 100 )。 
所有字符串由小写的英文字符组成。
Output

最长子串的长度。

Sample Input


lgcstraightlalongahisnstreet 
5
str
long
tree
biginteger
ellipse
Sample Output

12

思路:AC自动机+dp

#include <cstdio>#include <queue>#include <cstring>using namespace std;const int maxn=(int)1e6+10;const int inf=0x3f3f3f;struct Trie{       int node[maxn][26],fail[maxn],num[maxn],root,L;       int dp[maxn];       int newnode()       {            for(int i=0;i<26;i++) node[L][i]=-1;            num[L]=inf;            return L++;       }       void init()       {            L=0;            root=newnode();       }       void insert(char buf[])       {            int len=strlen(buf);            int now=root;            for(int i=0;i<len;i++)            {                if(node[now][buf[i]-'a']==-1)                    node[now][buf[i]-'a']=newnode();                now=node[now][buf[i]-'a'];            }            num[now]=strlen(buf);       }       void build()       {            queue<int> q;            for(int i=0;i<26;i++)            {                if(node[root][i]==-1)                 node[root][i]=root;                else                 fail[node[root][i]]=root,q.push(node[root][i]);            }            while(!q.empty())            {                int now=q.front();                q.pop();                for(int i=0;i<26;i++)                {                    if(node[now][i]==-1)                        node[now][i]=node[fail[now]][i];                    else                     {                        fail[node[now][i]]=node[fail[now]][i];                        q.push(node[now][i]);                        num[now]=min(num[now],num[fail[now]]);                     }                }            }       }       int query(char buf[])       {         int now=root,ans=0;         dp[0]=0;         for(int i=1;buf[i];i++)         {             dp[i]=dp[i-1]+1;             now=node[now][buf[i]-'a'];             dp[i]=min(dp[i],num[now]-1);             ans=max(ans,dp[i]);         }         return ans;       }};Trie ac;char buf[maxn];char s[maxn];int main(){    int n;    scanf("%s",buf+1);    scanf("%d",&n);    ac.init();    for(int i=1;i<=n;i++){        scanf("%s",s);ac.insert(s);    }    ac.build();    int ans=ac.query(buf);    printf("%d\n",ans);    return 0;}


原创粉丝点击