LA 3942 Remember the Word Trie树 DP

来源:互联网 发布:3季度经济数据 编辑:程序博客网 时间:2024/04/29 10:14
#include <iostream>#include <cstring>#include <queue>#include <stdlib.h>#include <stdio.h>using namespace std;/*思路:dp[i]=sum(dp[i+len(x)])dp[i]表示从字符i开始的字符串即后缀(s[i..L])的分解方案数。x为是 (s[i..L]的前缀。*/const int MAXM=400110;  //最大单词数量 * 最大单词长度const int SIZE=26;const int MAXN=300010;const int MOD=20071027;char Words[MAXN];int F[MAXN];struct Trie{    int ch[MAXM][SIZE];    int val[MAXM];    int sz;    inline void init()    {        sz=1;        val[0]=0;        memset(ch[0],0,sizeof(ch[0]));    }    inline int index(char c)    {        return c-'a';    }    void insert(char* s)    {        int u=0,len=strlen(s);        for (int i=0;i<len;i++)        {            int c=index(s[i]);            if (!ch[u][c])            {                memset(ch[sz],0,sizeof(ch[sz]));                val[sz]=0;                ch[u][c]=sz++;            }            u=ch[u][c];        }        val[u]=len;    }    void sear(char* s,int p,int len)    {        int u=0;        for (int i=0;i<len;i++)        {            int c=index(s[i]);            if (!ch[u][c])                return;            u=ch[u][c];            if (val[u])                F[p]=(F[p]+F[p+val[u]])%MOD;        }    }};Trie T;int main(){    int s,len,cas=1;    char temp[110];    while (scanf("%s",Words)!=EOF)    {        scanf("%d",&s);        len=strlen(Words);        T.init();        F[len]=1;        for (int i=0;i<s;i++)        {            scanf("%s",temp);            T.insert(temp);        }        for (int i=len-1;i>=0;i--)        {            F[i]=0;            T.sear(Words+i,i,len-i);        }        printf("Case %d: %d\n",cas++,F[0]);    }    return 0;}
0 0
原创粉丝点击