soj Article Decryption 字典树+DP

L - Article Decryption
Time Limit:0MS     Memory Limit:0KB     64bit IO Format:%lld & %llu

Description

Time Limit:1000ms Memory Limit:65536KB

Description

You are given an dictionary in which there are N words.
Also, you are given an article with the length of L and
there`s no punctuation.
How many way can you translate this article?

Input

The first line is an integer T which stands for the number of test cases.
Then T test cases follow.
The first line of a test case contains an integer N (1<=N<=1000).
Each of the following N lines contains one word . 
The length of each word is guaranteed to be less than or eaqul to 1000.
The next line contains some characters which describe the article. 
The characters are lowercase letters.

Output

For each case output its answer after mod by 835672545.

Sample Input

2
5
ab
cb
bc
ba
a
abcba
3
a
ba
ab
ababa

Sample Output

2
3

Hint

 

Author

onmylove

Source

 Preliminary (Single)先按单词建树。。。dp【i】代表i到n的方案数则 dp【i】=∑ (dp【j】) (i到j是个完整的单词)
#include<iostream>
#include<iostream>
#include<cstdio>
#include<math.h>
#include<algorithm>
#include<map>
#include<set>
#include<bitset>
#include<stack>
#include<queue>
#include<string.h>
#include<cstring>
#include<vector>
#include<time.h>
#include<stdlib.h>
using namespace std;
#define INF 0x3f3f3f3f
#define INFLL 0x3f3f3f3f3f3f3f3f
#define FIN freopen("input.txt","r",stdin);
#define mem(x,y) memset(x,y,sizeof(x));
typedef unsigned long long ULL;
typedef long long LL;
#define fuck(x) cout<<x<<endl;
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
typedef pair<pair<int,int>,int> PIII;
typedef pair<int,int> PII;
const int MX=1111;
const int P=835672545;
int n;
int rear=0;
int End[MX];
int to[MX][26];
int root;
int tree_new()
{
    rear++;
    End[rear]=0;
    for(int i=0; i<26; i++)to[rear][i]=0;
    return rear;
}
void tree_init()
{
    rear=0;
    root=tree_new();
}
void tree_add(char *s)
{
    int rt=root;
    for(char *ss=s; *ss; ss++)
    {
        if(to[rt][*ss-'a']==0)
            to[rt][*ss-'a']=tree_new();
        rt=to[rt][*ss-'a'];
    }
    End[rt]=1;
}
void tree_query(char *s,int *arr)
{
    int rt=root;
    int cnt=0;
    for(char *ss=s; *ss; ss++)
    {
        cnt++;
        rt=to[rt][*ss-'a'];
        if(rt==0) return;
        if(End[rt])arr[0]=(arr[0]+arr[cnt])%P;
    }
    return;
}
char s[MX*100];
int dp[MX*100];
int main()
{
    FIN;
    int T;
    cin>>T;
    while(T--)
    {
        cin>>n;
        tree_init();
        for(int i=1; i<=n; i++)
        {
            scanf("%s",s);
            tree_add(s);
        }
        scanf("%s",s);
        int len=strlen(s);
        for(int i=0; i<len; i++)dp[i]=0;
        dp[len]=1;
        for(int i=len-1; i>=0; i--)
        {
            tree_query(s+i,dp+i);
        }
        cout<<dp[0]<<endl;
    }
    return 0;
}


 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值