UVALive - 3942(trie

Description

Neal is very curious about combinatorial problems, and now here comes a problem about words. Knowing that Ray has a photographic memory and this may not trouble him, Neal gives it to Jiejie.

Since Jiejie can‘t remember numbers clearly, he just uses sticks to help himself. Allowing for Jiejie‘s only 20071027 sticks, he can only record the remainders of the numbers divided by total amount of sticks.

The problem is as follows: a word needs to be divided into small pieces in such a way that each piece is from some given set of words. Given a word and the set of words, Jiejie should calculate the number of ways the given word can be divided, using the words in the set.

Input

The input file contains multiple test cases. For each test case: the first line contains the given word whose length is no more than 300 000.

The second line contains an integer S , 1S4000 .

Each of the following S lines contains one word from the set. Each word will be at most 100 characters long. There will be no two identical words and all letters in the words will be lowercase.

There is a blank line between consecutive test cases.

You should proceed to the end of file.

Output

For each test case, output the number, as described above, from the task description modulo 20071027.

Sample Input

abcd
4
a
b
cd
ab

Sample Output

Case 1: 2
Trie上的DP,第一次写trie,发现不能写数组版的啊,比指针版的慢了好多倍。。。。。。。
const int maxv=4e5+3;
const ll mod=20071027;
char s[maxv];
int S;
int idx(char c){return c-‘a‘;}
struct trie{
    int ch[maxv][27];
    bool ma[maxv];
    int sz;
    void clear(){
        memset(ch,0,sizeof ch);
        memset(ma,0,sizeof ma);
        sz=1;
    }
    void insert(char *s){
        int n=strlen(s);
        int u=0,v;
        for(int i=0;i<n;i++){
            v=idx(s[i]);
            if(ch[u][v])
                u=ch[u][v];
            else{
                ch[u][v]=sz++;
                u=sz-1;
            }
        }
        ma[u]=1;
    }
}T;
char tmp[maxv];
const int maxdp=3e5+30;
ll dp[maxdp];
int main(){
    int t=0;
    while(scanf("%s",s)!=EOF){
        int ssz=strlen(s);
        t++;
        cin>>S;
        T.clear();
        memset(dp,0,sizeof dp);
        while(S--){
            scanf("%s",tmp);
            T.insert(tmp);
        }
        dp[ssz]=1;
        for(int i=ssz-1;i>=0;i--){////从最后一个字符开始匹配
            char *su=&s[i];
            int susz=strlen(su);
            int u=0;
            for(int j=0;j<susz;j++){
                int v=idx(su[j]);
                if(T.ch[u][v]&&T.ma[T.ch[u][v]]){
                        dp[i]=(dp[i+j+1]+dp[i])%mod;
                }
                if(T.ch[u][v]) u=T.ch[u][v];
                else break;
            }
        }
        printf("Case %d: %lld\n",t,dp[0]);
    }
    return 0;
}
时间: 2024-11-05 11:29:45

UVALive - 3942(trie的相关文章

UVALive 3942 - Remember the Word(DP,数组Trie+指针Trie)

UVALive 3942 - Remember the Word(DP,数组Trie+指针Trie) ACM 题目地址: UVALive 3942 - Remember the Word 题意: 给一些单词,然后给一个长的单词,问有几种方法能组成这个大单词,单词可以重复用. 分析: DP[i]=sum{DP[j} (i<j<len),从后往前求. 本来用数组Trie写得爽爽的,1A了. 发现2s多,不能忍! 然后用指针Trie写了一遍,各种出错,整个人都不好了... 研究了一遍别人代码,发现快

UVALive - 3942 Remember the Word[Trie DP]

UVALive - 3942 Remember the Word Neal is very curious about combinatorial problems, and now here comes a problem about words. Know- ing that Ray has a photographic memory and this may not trouble him, Neal gives it to Jiejie. Since Jiejie can’t remem

UVALive - 3942 - Remember the Word (Trie树)

UVALive - 3942 Remember the Word Time Limit: 3000MS   Memory Limit: Unknown   64bit IO Format: %lld & %llu Submit Status Description Neal is very curious about combinatorial problems, and now here comes a problem about words. Knowing that Ray has a p

UVALive 3942 Remember the Word 字典树+dp

/** 题目:UVALive 3942 Remember the Word 链接:https://vjudge.net/problem/UVALive-3942 题意:给定一个字符串(长度最多3e5)和m个单词(每个单词长度最多100).单词都是不同的.该字符串可以由若干个单词组成,问最多有多少种组合方式. 思路:字典树+dp 用字典树处理好m个单词,定义dp[i]表示从i开始的字符串可以由单词组成的方式数. 那么dp[i] += dp[i+j]; j表示某个单词和字符串的[i,i+j-1]匹配

【暑假】[实用数据结构]UVAlive 3942 Remember the Word

UVAlive 3942 Remember the Word 题目: Remember the Word Time Limit: 3000MS   Memory Limit: Unknown   64bit IO Format: %lld & %llu Submit Status Description Neal is very curious about combinatorial problems, and now here comes a problem about words. Know

UVALive - 3942 Remember the Word[树状数组]

UVALive - 3942 Remember the Word A potentiometer, or potmeter for short, is an electronic device with a variable electric resistance. It has two terminals and some kind of control mechanism (often a dial, a wheel or a slide) with which the resistance

(trie)UVALive - 3942 Remember the Word

题目链接 设d[i]表示从下标i的字符开始的字符串的分解方法数,显然有倒序的递推公式. 需要求每个位置开始是否能组成模式串的前缀,才可以建立正确的递推. 1 #include <iostream> 2 #include <string> 3 #include <algorithm> 4 #include <cstring> 5 #include <cstdio> 6 #include <cmath> 7 #include <qu

UVaLive 3942 Remember the Word (dp+字典树)

Remember the Word DescriptionNeal is very curious about combinatorial problems, and now here comes a problem about words. Knowing that Ray has a photographic memory and this may not trouble him, Neal gives it to Jiejie. Since Jiejie can’t remember nu

UVALive 3942 Remember the Word

空降链接:https://vjudge.net/problem/UVALive-3942 题意: 给出一个字符串s(strlen(s)<=3e5)和一堆字符串str[MAX](MAX<=4000,strlen(str[i])<=100),每个str[i]可以用无限次,求用str这些字符串拼接成s的方案数. 题解: 根据题意肯定要先建棵trie...然后开始xjbDP了.因为每个串的长度都<=100,所以每次可以枚举s的下标i作为起始坐标,在字典树中找当前下标为起点的前缀,如果在与字