AC自动机+数位DP。

  大致题意:

    BCD码就是把一个数十进制下的每一位分别用4位的二进制表示。

    给你一坨01串,问你在一个区间内,有多少个数的BCD码不包含任何一个字符串。

  因为涉及到多个串的匹配问题...所以要在AC自动机上DP

  f[i][j]表示在自动机上的节点i,再往后走j步 的合法方案数。(合法就是说,经过的路径上不包含任何一个给定字符串)

  建完AC自动机后,把非法的节点都删掉,再求出CH[i][j]表示从i节点出发,经过数字j后到达的节点(0<=j<=9),这样好转移= =。

  一开始想写递归版本的。。前导0什么的完全无力TAT

  后来干脆用记忆化搜索求f数组,然后统计答案的时候用正常姿势。。这样好写多了>_<

  结果交完直接#1了。。我是没看出来自己的写法哪里常数优越= =

  其实这题只比普通模版题多了个AC自动机而已。。。其他甚至还简单点

  就算是递归版的,只要好好想一下前导零的问题就行了吧...网上递归版的标程也不长

 #include<cstdio>
#include<iostream>
#include<cstring>
using namespace std;
const int modd=;
int fail[],ch[][];
int CH[][];
int f[][],u[][];//f[i][j]在自动机上的i节点时,再往后走j步的合法方案数
int i,j,k,n,m,tot,T,ans,len;
bool gg[]; char s[];int dl[]; inline void insert(int len){
int i,now=;
for(i=;i<len;i++)
s[i]-='',now=ch[now][s[i]]?ch[now][s[i]]:(ch[now][s[i]]=++tot);
gg[now]=;
}
inline void build(){
int l=,r=,i,now,tmp;
while(l<r){
now=dl[++l];
for(i=;i<=;i++)if(ch[now][i]){
for(tmp=fail[now];tmp&&!ch[tmp][i];tmp=fail[tmp]);
fail[ch[now][i]]=(now==)?:ch[tmp][i]; gg[ch[now][i]]|=gg[fail[ch[now][i]]]|gg[now];
dl[++r]=ch[now][i];
}else{
for(tmp=fail[now];tmp&&!ch[tmp][i];tmp=fail[tmp]);
ch[now][i]=ch[tmp][i];
}
}
for(i=;i<=tot;i++)for(j=;j<=;j++)if(gg[ch[i][j]]||gg[i])ch[i][j]=-;
for(i=;i<=tot;i++)if(!gg[i])
for(j=;j<=;j++){
for(now=i,k=;k&&now!=-;k>>=)
now=ch[now][(k&j)!=];
CH[i][j]=now;//printf(" %d->%d %d\n",i,j,CH[i][j]);
}
for(i=;i<=tot;i++)if(!gg[i])f[i][]=,u[i][]=T;
}
inline int dfs(int x,int step){
if(u[x][step]==T)return f[x][step];
int ans=;
for(int i=;i<=;i++)if(CH[x][i]!=-)
ans+=dfs(CH[x][i],step-),ans-=ans>=modd?modd:;
u[x][step]=T,f[x][step]=ans;//printf(" f: %d %d %d\n",x,step,f[x][step]);
return ans;
}
inline int get(int len){//求区间[1,len)内合法方案数
register int i,j,ans=,now;
for(i=;i<len;i++)s[i]-=;
for(i=;i<len;i++)for(j=;j<=;j++)if(CH[][j]!=-)
ans+=dfs(CH[][j],i-),ans-=ans>=modd?modd:;
for(i=;i<s[];i++)if(CH[][i]!=-)ans+=dfs(CH[][i],len-),ans-=ans>=modd?modd:; now=CH[][s[]];
for(i=;i<len&&now!=-;i++){
for(j=;j<s[i];j++)if(CH[now][j]!=-)ans+=dfs(CH[now][j],len-i-),ans-=ans>=modd?modd:;
now=CH[now][s[i]];
}
return ans;
}
inline void add(){
int i,j;
for(i=len-;i>=;i--)if(s[i]!='')break;
if(i>=)
for(s[i]++,j=i+;j<len;j++)s[j]='';
else{
for(s[]='',i=;i<=len;i++)s[i]='';
len++;
}
}
int main(){
for(scanf("%d",&T);T;T--){
scanf("%d",&n);memset(gg,,tot+);memset(ch,,(tot+)<<);tot=;
for(i=;i<=n;i++)
scanf("%s",s),insert(strlen(s));
build();
scanf("%s",s);len=strlen(s);ans=-get(len);
scanf("%s",s);len=strlen(s);add();ans+=get(len);
if(ans<)ans+=modd;
printf("%d\n",ans);
}
return ;
}

[ZOJ3494]BCD Code的更多相关文章

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

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

  2. ZOJ 3494 BCD Code(AC自动机+数位DP)

    BCD Code Time Limit: 5 Seconds      Memory Limit: 65536 KB Binary-coded decimal (BCD) is an encoding ...

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

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

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

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

  5. zoj 3494:BCD Code

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

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

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

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

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

  8. FZU 2113 BCD Code 数位dp

    数位dp,但是很奇怪的是我在虚拟oj上用GUC C++提交会wa,用Visual c++提交正确,但是加上注释后提交又莫名CE--好任性啊 0 ,0 题目思路:看代码吧 注释很详细 #include& ...

  9. [转]数位dp小记

    转载自:http://blog.csdn.net/guognib/article/details/25472879 参考: http://www.cnblogs.com/jffifa/archive/ ...

随机推荐

  1. 从初识Maven到使用Maven进行依赖管理和项目构建

    前些天就安装了Maven,以备自己以后整合项目用,尤其是我们的ssh,ssm项目.想必好多人在开始的时候并不清楚Maven是什么,它能够帮助我们干什么. 所以在学习Maven之前我们一定要知道它是什么 ...

  2. KVM_虚拟化技术

    1 什么是 KVM KVM 是指基于 Linux 内核的虚拟机(Kernel-based Virtual Machine). 2006 年 10 月,由以色列的 Qumranet 组织开发的一种新的“ ...

  3. linux下PHP后台配置极光推送问题

    一.composer.json配置注意空格 按照极光推送官网所述,在composer.json下写入: "require": { "jpush/jpush": ...

  4. Java定时器应用

    在Java多线程中,有的时候,我们需要按照指定间隔时间来执行一些任务,这时,我们就要用到定时器.我们在这里以Java中的Timer定时器为例,演示定时器的应用. 请看下述代码: import java ...

  5. MySQL MVCC机制

    本文同时发表在https://github.com/zhangyachen/zhangyachen.github.io/issues/68 行结构 每一行额外包含三个隐藏字段: DB_TRX_ID:事 ...

  6. ArcGIS 网络分析[2.2] 服务区分析

    什么是服务区? 我们先提一个很常见的社会现象:一个医院,如果要发起抢救,那么10分钟内能去多远? 时间就是生命,当结合道路网的阻力进行最短路径分析时,得到的可达的覆盖区域,这个区域就是服务区. 服务区 ...

  7. ActiveMQ (二) 常用配置简介

    ActiveMQ的主要配置文件 ActiveMQ的一些常用的属性很多可以在对应的配置文件中进行配置的.比如访问web console的管理端的端口,用户名密码,连接MQ时的用户名和密码,持久化设置,是 ...

  8. 我搞zabbix的那两天(2)

    摘要:前一篇(我搞zabbix的那两天(1))我介绍了Zabbix的安装部署以及遇到的问题,这一篇将介绍zabbix 使用及短信等告警实现!!! Zabbix主界面及汉化方法介绍 1.1 初始化主界面 ...

  9. WebRTC 入门到放弃(一)WebRTC

    前言 WebRTC,名称源自网页实时通信(Web Real-Time Communication)的缩写,是一个支持网页浏览器进行实时语音对话或视频对话的技术,是谷歌2010年以6820万美元收购Gl ...

  10. php mysql语句预编译(preparestatement)

    预处理语句用于执行多个相同的 SQL 语句,并且执行效率更高. 预处理语句的工作原理如下: 预处理:创建 SQL 语句模板并发送到数据库.预留的值使用参数 "?" 标记 .例如: ...