背单词 Remember the world LA 3942

#include<cstring>
#include<iostream>
#include<cstdio>
using namespace std;
const int MAXN = 4000 * 100 + 10;
const int sigma = 26;
const int MAXNn = 300010;
const int mod = 20071027;
char words[ MAXNn ];
int  dp[ MAXNn ];
struct Trie
{
    int ch[MAXN][sigma];
    int value[MAXN];
    int sz;
    Trie() { sz = 1; memset( ch[0] , 0 , sizeof(ch[0]) ); }
    void init() { sz = 1; memset( ch[0] , 0 , sizeof(ch[0]) ); }
    int dix(char c) { return c - 'a' ; }
    void Insert( char *s)
    {
        int len = strlen( s );
        int u = 0;
        int i , cur ;
        for( i = 0 ; i < len ; i++ )
        {
            cur = dix( s[i] );
            if( !ch[u][cur] )
            {
                memset( ch[sz] , 0 , sizeof( ch[sz] ) );
                value[sz] = 0;
                ch[u][cur] = sz++;
            }
            u = ch[u][cur];
        }
        value[ u ] = len;
    }
}tree;

int dfs( int cur , int len )
{
    if( dp[cur] != 0 )
        return dp[cur];
    if( cur == len )
        return 1;
    else if( cur > len )
        return 0;
    int sum = 0 , i , tmp , u = 0 ;
    for( i = cur ; i < len ; i++ )
    {
        tmp = tree.dix( words[i] );
        if( tree.ch[u][tmp] )
        {
            u = tree.ch[u][tmp];
            if( tree.value[u] )
            {
                sum += dfs( i+1 , len ) % mod;
            }
        }
        else
            break;
    }
    dp[cur] = sum % mod;
    return sum;
}

int main()
{
#ifndef ONLINE_JUDGE
    freopen("in.txt","r",stdin);
#endif
    char tmp[110];
    int  s , len , i;
    int count = 1;
    while( ~scanf("%s",words) )
    {
        scanf("%d",&s);
        len = strlen( words );
        tree.init();
        for( i = 0 ; i < s ; i++ )
        {
            scanf("%s",tmp );
            tree.Insert( tmp );
        }
        memset( dp , 0 ,sizeof(dp) );
        dfs( 0  , len );
        printf("Case %d: %d\n",count++ , dp[0] % mod);
    }
    return 0;
}

 

转载于:https://www.cnblogs.com/zhping/p/4479965.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值