UVALA3942(关于字典树)

来源:互联网 发布:python idle教程 编辑:程序博客网 时间:2024/06/18 03:32
题目链接:http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=22109
解法:我们写出递推方程d[i]=sum[d[i+len(x)],d[i]  表示以i开始的字符粗的分解方案数。对于这个我们以算出他的复杂度n*m,n为单词个数,m为查找的复杂度。当我们把单词存在数组遍历时,复杂度为m(4000*100)。这个会超时的。由于这里用到了前缀,我们可以用trie来优化。
关于字典树:字典树可以用来处理前缀相关的问题,用来优化字符查询和统计的问题。查询一个单词的复杂度为这个词的长度。我们用数组ch【i】【j】来表示节点i的为j的字母的位置。然后我们就可以来构造字典树,一般用数组来写,这样调试方便。多组输入的不要忘记初始化!!!
代码如下:
#include<algorithm>
#include<iostream>
#include<cmath>
#include<map>
#include<string.h>
#include<cstring>
#include<vector>
#include<queue>
#include<stdio.h>
using namespace std;
#define ll  long long int
#define maxn 400008
int len[maxn],cnt_len,d[maxn],ed;
char s[maxn],sc[maxn];
const int mod=20071027;

struct trie
{
    public:
    int ch[maxn][30];
    int val[maxn];
    int sz=1;
   void  tt()  {   sz=1;   memset(ch[0],0,sizeof(ch[0]) );  };
    int idx(char c)  {  return c-'a';  }

    void insert_(char *s2,int v)
    {
        int u=0,n=strlen(s2);
        for(int i=0;i<n;i++)
        {
            int c=idx(s2[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]=v;
    };
    void  search_(char *s1)
    {
        int u=0,n=strlen(s1);
        for(int i=0;i<n;i++)
        {
            int c=idx(s1[i]);
            if(!ch[u][c])
                return ;
            u=ch[u][c];
            if(val[u])
            {
                len[cnt_len++]=i+1;
            }
        }
    }
}t;
int main(void)
{
    //freopen("in.txt","r",stdin);
   int pvis,dd;
   pvis=0;
   while(scanf("%s",s)!=EOF)
   {
       t.tt();
        memset(len,0,sizeof(len));
        memset(d,0,sizeof(d));
        ed=cnt_len=0;
       int n=strlen(s);
       scanf("%d",&dd);
       for(int i=0;i<dd;i++)
       {
           scanf("%s",sc);
           t.insert_(sc,1);
       }
       for(int i=n-1;i>=0;i--)
       {
           cnt_len=0;
           t.search_(s+i);
            d[n]=1;
            for(int j=0;j<cnt_len;j++)
           {
               d[i]=(d[i]+d[i+len[j]])%mod;
           }


       }
       printf("Case %d: %d\n",++pvis,d[0]);
   }

}
0 0
原创粉丝点击