LA 3942 3942 - Remember the Word

/*
   LA 3942
   d[i]=sum{d(i+len(x))}|单词x是S[i...L]的前缀
   先把所有的单词组织成Trie,然后在Trie中查找 
*/

#include<stdio.h>
#include<string.h>

const int maxnode = 500000;
const int sigma_size = 26;
const int N = 300010;
const int mod = 20071027;

int ch[maxnode][sigma_size];
int val[maxnode];
int sz;
int dp[N];
int num,begin;

int idx(char c)
{ 
    return c - 'a';
}
 
void Trie_init() 
{ 
     sz = 1; 
     memset(ch[0],0,sizeof(ch[0])); 
}

void insert(char *s,int v)
{
   int u=0,n=strlen(s);
   
   for(int i=0;i<n;i++)
   {
      int c=idx(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]=v;
}
void query(char *s)
{
    int u=0;
    for(int i=0;s[i];i++)
    {
        int c=idx(s[i]);
        if(ch[u][c])
        {
           u=ch[u][c];
           if(val[u])
           {
             num=(num+dp[begin+i+1])%mod;          
           }         
        }
        else
         return ;   
     } 
}


int main()
{
    char s1[N];
    int i;
    char s2[110];
    int n,len;
    int Case=1;
  while(scanf("%s",&s1)!=EOF)
  {
     Trie_init() ;                    
     scanf("%d",&n);
     memset(dp,0,sizeof(dp));
     while(n--)
     {
        scanf("%s",&s2);
        insert(s2,1);
     }    
     len=strlen(s1);
     dp[len]=1;
     for(i=len-1;i>=0;i--)
     {
        num=0;
        begin=i;
        query(&s1[i]);
        dp[i]=num;               
     }
     printf("Case %d: %d\n",Case++,dp[0]); 
  }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值