ZOJ 3494 BCD Code(AC自动机+数位DP)
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)的更多相关文章
- zoj3494 BCD Code(AC自动机+数位dp)
Binary-coded decimal (BCD) is an encoding for decimal numbers in which each digit is represented by ...
- zoj3494BCD Code(ac自动机+数位dp)
l链接 这题想了好一会呢..刚开始想错了,以为用自动机预处理出k长度可以包含的合法的数的个数,然后再数位dp一下就行了,写到一半发现不对,还要处理当前走的时候是不是为合法的,这一点无法移到trie树上 ...
- 【HDU3530】 [Sdoi2014]数数 (AC自动机+数位DP)
3530: [Sdoi2014]数数 Time Limit: 10 Sec Memory Limit: 512 MBSubmit: 682 Solved: 364 Description 我们称一 ...
- 【bzoj3530】[Sdoi2014]数数 AC自动机+数位dp
题目描述 我们称一个正整数N是幸运数,当且仅当它的十进制表示中不包含数字串集合S中任意一个元素作为其子串.例如当S=(22,333,0233)时,233是幸运数,2333.20233.3223不是幸运 ...
- BZOJ 3530 [SDOI2014]数数 (Trie图/AC自动机+数位DP)
题目大意:略 裸的AC自动机+数位DP吧... 定义f[i][x][0/1]表示已经匹配到了第i位,当前位置是x,0表示没到上限,1到上限,此时数是数量 然而会出现虚拟前导零,即前几位没有数字的情况, ...
- BCD Code ZOJ - 3494 AC自动机+数位DP
题意: 问A到B之间的所有整数,转换成BCD Code后, 有多少个不包含属于给定病毒串集合的子串,A,B <=10^200,病毒串总长度<= 2000. BCD码这个在数字电路课上讲了, ...
- ZOJ 3494 BCD Code(AC自动机 + 数位DP)题解
题意:每位十进制数都能转化为4位二进制数,比如9是1001,127是 000100100111,现在问你,在L到R(R <= $10^{200}$)范围内,有多少数字的二进制表达式不包含模式串. ...
- ZOJ 3494 BCD Code (数位DP,AC自动机)
题意: 将一个整数表示成4个bit的bcd码就成了一个01串,如果该串中出现了部分病毒串,则是危险的.给出n个病毒串(n<=100,长度<21),问区间[L,R]中有几个数字是不含病毒串的 ...
- ZOJ 3494 BCD Code (AC自己主动机 + 数位DP)
题目链接:BCD Code 解析:n个病毒串.问给定区间上有多少个转换成BCD码后不包括病毒串的数. 很奇妙的题目. . 经典的 AC自己主动机 + 数位DP 的题目. 首先使用AC自己主动机,得到b ...
随机推荐
- 【leetcode】Integer to Roman
Integer to Roman Given an integer, convert it to a roman numeral. Input is guaranteed to be within t ...
- MST:Out of Hay(POJ 2395)
缺乏粮草 题目大意:一群牛要修建一些通道,到各个农场距离总和要最小,求这些通道的最大值 水题了,一个Kruskal搞定 #include <iostream> #include <f ...
- codeforces 496B. Secret Combination 解题报告
题目链接:http://codeforces.com/problemset/problem/496/B 题目意思:给出 n 位数你,有两种操作:1.将每一位数字加一(当某一位 > 9 时只保存个 ...
- sql server 取日期
Select CONVERT(varchar(100), GETDATE(), 0): 05 16 2006 10:57AM Select CONVERT(varchar(100), GETDATE( ...
- s:iterator,s:if与OGNL的嵌套使用
今天在写代码时,遇到个如下问题,要求当前登陆用户的id与系统参数类型代码所属维护人的id相同时,显示单选框.如下效果: 代码如下: <s:iterator value="vo.page ...
- 20145213 《Java程序设计》实验四 Android开发基础
20145213 <Java程序设计>实验四 Android开发基础 说在前面的话 不同以往实验,对于这次实验具体内容我是比较茫然的.因为点我,打开实验四的链接居然能飘出一股熟悉的味道,这 ...
- Xcode找不到模拟器
今天新建的工程,突然发现模拟器找不到了,之前遇到过忘记怎么解决了,于是再次记录下解决方法. 首先说下问什么找不到模拟器了,原因就是之前运行的版本和现在xcode的版本不同(的确,我从 Xcode7.3 ...
- ubuntu 添加环境变量
转自:http://hi.baidu.com/mario05/item/02b6d60ff7371136a2332a48 Ubuntu Linux系统环境变量配置文件:/etc/profile : 在 ...
- NYOJ题目1048破门锁
- Hadoop-2.X HA模式下的FSImage和EditsLog合并过程
补充了一下NameNode启动过程中有关FSImage与EditsLog的相关知识. 一.什么是FSImage和EditsLog 我们知道HDFS是一个分布式文件存储系统,文件分布式存储在多个Data ...