BCD Code


Time Limit: 5 Seconds      Memory Limit: 65536 KB

Binary-coded decimal (BCD) is an encoding for decimal numbers in which each digit is represented by its own binary sequence. To encode a decimal number using the common BCD encoding, each decimal digit is stored in a 4-bit nibble:

Decimal:    0     1     2     3     4     5     6     7     8     9
BCD: 0000 0001 0010 0011 0100 0101 0110 0111 1000 1001

Thus, the BCD encoding for the number 127 would be:

 0001 0010 0111

We are going to transfer all the integers from A to B, both inclusive, with BCD codes. But we find that some continuous bits, named forbidden code, may lead to errors. If the encoding of some integer contains these forbidden codes, the integer can not be transferred correctly. Now we need your help to calculate how many integers can be transferred correctly.

Input

There are multiple test cases. The first line of input is an integer T ≈ 100 indicating the number of test cases.

The first line of each test case contains one integer N, the number of forbidden codes ( 0 ≤ N ≤ 100). Then N lines follow, each of which contains a 0-1 string whose length is no more than 20. The next line contains two positive integers A and B. Neither A or B contains leading zeros and 0 < A ≤ B < 10200.

Output

For each test case, output the number of integers between A and B whose codes do not contain any of the N forbidden codes in their BCD codes. For the result may be very large, you just need to output it mod 1000000009.

Sample Input

3
1
00
1 10
1
00
1 100
1
1111
1 100

Sample Output

3
9
98

References


Author: GUAN, Yao
Contest: The 8th Zhejiang Provincial Collegiate Programming Contest

非常神奇的题目。。

首先使用AC自动机,得到bcd[i][j]表示状态i,加了数字j以后到达的状态,为-1表示不能转移

然后就是数位DP了

注意记录为0的状态

//============================================================================
// Name : ZOJ.cpp
// Author :
// Version :
// Copyright : Your copyright notice
// Description : Hello World in C++, Ansi-style
//============================================================================ #include <iostream>
#include <stdio.h>
#include <string.h>
#include <algorithm>
#include <queue>
using namespace std; struct Trie
{
int next[][],fail[];
bool end[];
int root,L;
int newnode()
{
for(int i = ;i < ;i++)
next[L][i] = -;
end[L++] = false;
return L-;
}
void init()
{
L = ;
root = newnode();
}
void insert(char buf[])
{
int len = strlen(buf);
int now = root;
for(int i = ;i < len ;i++)
{
if(next[now][buf[i]-''] == -)
next[now][buf[i]-''] = newnode();
now = next[now][buf[i]-''];
}
end[now] = true;
}
void build()
{
queue<int>Q;
fail[root] = root;
for(int i = ;i < ;i++)
if(next[root][i] == -)
next[root][i] = root;
else
{
fail[next[root][i]] = root;
Q.push(next[root][i]);
}
while(!Q.empty())
{
int now = Q.front();
Q.pop();
if(end[fail[now]])end[now] = true;
for(int i = ;i < ;i++)
if(next[now][i] == -)
next[now][i] = next[fail[now]][i];
else
{
fail[next[now][i]] = next[fail[now]][i];
Q.push(next[now][i]);
}
}
}
};
Trie ac; int bcd[][];
int change(int pre,int num)
{
if(ac.end[pre])return -;
int cur = pre;
for(int i = ;i >= ;i--)
{
if(ac.end[ac.next[cur][(num>>i)&]])return -;
cur = ac.next[cur][(num>>i)&];
}
return cur;
}
void pre_init()
{
for(int i = ;i <ac.L;i++)
for(int j = ;j <;j++)
bcd[i][j] = change(i,j);
}
const int MOD = ;
long long dp[][];
int bit[]; long long dfs(int pos,int s,bool flag,bool z)
{
if(pos == -)return ;
if(!flag && dp[pos][s]!=-)return dp[pos][s];
long long ans = ;
if(z)
{
ans += dfs(pos-,s,flag && bit[pos]==,true);
ans %= MOD;
}
else
{
if(bcd[s][]!=-)ans += dfs(pos-,bcd[s][],flag && bit[pos]==,false);
ans %= MOD;
}
int end = flag?bit[pos]:;
for(int i = ;i<=end;i++)
{
if(bcd[s][i]!=-)
{
ans += dfs(pos-,bcd[s][i],flag&&i==end,false);
ans %=MOD;
}
}
if(!flag && !z)dp[pos][s] = ans;
return ans;
} long long calc(char s[])
{
int len = strlen(s);
for(int i = ;i < len;i++)
bit[i] = s[len--i]-'';
return dfs(len-,,,);
}
char str[];
int main()
{
// freopen("in.txt","r",stdin);
// freopen("out.txt","w",stdout);
int T;
scanf("%d",&T);
int n;
while(T--)
{
ac.init();
scanf("%d",&n);
for(int i = ;i < n;i++)
{
scanf("%s",str);
ac.insert(str);
}
ac.build();
pre_init();
memset(dp,-,sizeof(dp));
int ans = ;
scanf("%s",str);
int len = strlen(str);
for(int i = len -;i >=;i--)
{
if(str[i]>'')
{
str[i]--;
break;
}
else str[i] = '';
}
ans -= calc(str);
ans %=MOD;
scanf("%s",str);
ans += calc(str);
ans %=MOD;
if(ans < )ans += MOD;
printf("%d\n",ans);
}
return ;
}

 

ZOJ 3494 BCD Code(AC自动机+数位DP)的更多相关文章

  1. zoj3494 BCD Code(AC自动机+数位dp)

    Binary-coded decimal (BCD) is an encoding for decimal numbers in which each digit is represented by ...

  2. zoj3494BCD Code(ac自动机+数位dp)

    l链接 这题想了好一会呢..刚开始想错了,以为用自动机预处理出k长度可以包含的合法的数的个数,然后再数位dp一下就行了,写到一半发现不对,还要处理当前走的时候是不是为合法的,这一点无法移到trie树上 ...

  3. 【HDU3530】 [Sdoi2014]数数 (AC自动机+数位DP)

    3530: [Sdoi2014]数数 Time Limit: 10 Sec  Memory Limit: 512 MBSubmit: 682  Solved: 364 Description 我们称一 ...

  4. 【bzoj3530】[Sdoi2014]数数 AC自动机+数位dp

    题目描述 我们称一个正整数N是幸运数,当且仅当它的十进制表示中不包含数字串集合S中任意一个元素作为其子串.例如当S=(22,333,0233)时,233是幸运数,2333.20233.3223不是幸运 ...

  5. BZOJ 3530 [SDOI2014]数数 (Trie图/AC自动机+数位DP)

    题目大意:略 裸的AC自动机+数位DP吧... 定义f[i][x][0/1]表示已经匹配到了第i位,当前位置是x,0表示没到上限,1到上限,此时数是数量 然而会出现虚拟前导零,即前几位没有数字的情况, ...

  6. BCD Code ZOJ - 3494 AC自动机+数位DP

    题意: 问A到B之间的所有整数,转换成BCD Code后, 有多少个不包含属于给定病毒串集合的子串,A,B <=10^200,病毒串总长度<= 2000. BCD码这个在数字电路课上讲了, ...

  7. ZOJ 3494 BCD Code(AC自动机 + 数位DP)题解

    题意:每位十进制数都能转化为4位二进制数,比如9是1001,127是 000100100111,现在问你,在L到R(R <= $10^{200}$)范围内,有多少数字的二进制表达式不包含模式串. ...

  8. ZOJ 3494 BCD Code (数位DP,AC自动机)

    题意: 将一个整数表示成4个bit的bcd码就成了一个01串,如果该串中出现了部分病毒串,则是危险的.给出n个病毒串(n<=100,长度<21),问区间[L,R]中有几个数字是不含病毒串的 ...

  9. ZOJ 3494 BCD Code (AC自己主动机 + 数位DP)

    题目链接:BCD Code 解析:n个病毒串.问给定区间上有多少个转换成BCD码后不包括病毒串的数. 很奇妙的题目. . 经典的 AC自己主动机 + 数位DP 的题目. 首先使用AC自己主动机,得到b ...

随机推荐

  1. 【leetcode】Merge Intervals

    Merge Intervals Given a collection of intervals, merge all overlapping intervals. For example,Given  ...

  2. struts2 校验demo

    综合练习: <validators> <field name="username"> <field-validator type="requ ...

  3. Qt 信号槽如何传递参数(或带参数的信号槽)

                                    信号槽如何传递参数(或带参数的信号槽) 利用Qt进行程序开发时,有时需要信号槽来完成参数传递.带参数的信号槽在使用时,有几点需要注意的地 ...

  4. mysql创建用户

    mysql创建用户 创建用于localhost连接的用户并指定密码 mysql> create user 'pcom'@'localhost' identified by 'aaa7B2249' ...

  5. spring3 的restful API RequestMapping介绍

    原文链接:http://www.javaarch.net/jiagoushi/694.htm spring3 的restful API RequestMapping介绍 在spring mvc中 @R ...

  6. 【转】Android Support v4、v7、v13的区别和应用场景

    google提供了Android Support Library package 系列的包来保证来高版本sdk开发的向下兼容性,即我们用4.x开发时,在1.6等版本上,可以使用高版本的有些特性,如fr ...

  7. sqlserverJDBC驱动链接

    final String DRIVER="com.microsoft.jdbc.sqlserver.SQLServerDriver"; final String URL=" ...

  8. 解决eclipse Maven 主项目不能刷新maven

    项目->.project -> 增加<?xml version="1.0" encoding="UTF-8"?><projectD ...

  9. "稀奇古怪的"delete this

    myClass::foo(){     delete this; } .. void func(){     myClass *a = new myClass();     a->foo(); ...

  10. NYOJ题目97兄弟郊游问题

    aaarticlea/png;base64,iVBORw0KGgoAAAANSUhEUgAAAr8AAAHxCAIAAADrwUM4AAAgAElEQVR4nO3dLXLjytfH8f8mzLOQYC