「SDOI2014」数数

题目描述

我们称一个正整数 \(N\) 是幸运数,当且仅当它的十进制表示中不包含数字串集合 \(S\) 中任意一个元素作为其子串。

例如当 \(S=(\)22, 333, 0233\()\) 时,233 是幸运数,2333202333223 不是幸运数。

给定 \(N\) 和 \(S\),计算不大于 \(N\) 的幸运数个数。

输入格式

输入的第一行包含整数 \(N\)。

接下来一行一个整数 \(M\),表示 \(S\) 中元素的数量。 接下来 \(M\) 行,每行一个数字串,表示 \(S\) 中的一个元素。

输出格式

输出一行一个整数,表示答案模 \(10^9+7\) 的值。

数据范围与提示

我们以 \(l\) 表示 \(N\) 的长度,\(L\) 表示 \(S\) 中所有串长度之和。

对于所有数据,\(1 \leq l \leq 1200 ,\ 1 \leq M \leq 100 ,\ 1 \leq L \leq 1500\)。


关于多子串的东西可以想到AC自动机,可以在上面dp。

\(dp_{i,j,0/1}\)代表\(i\sim n\)位数字目前在AC自动机上匹配到节点\(j\)是否有最高位限制。

最后一位可以像数位dp那样非常简单的转移,有个坑点是\(S\)中有前导\(0\),但是\(N\)中没有。

有一种简单的处理方法是在建完AC自动机后把边\(ch[root][0]\)删掉


Code:

#include <cstdio>
#include <cstring>
const int mod=1e9+7;
const int N=1520;
inline void add(int &x,int y){x=x+y>=mod?x+y-mod:x+y;}
char s[N],t[N];
int ch[N][10],endro[N],fail[N],tot,q[N],l=1,r,bit[N],dp[N][N][2];
void ins()
{
scanf("%s",s+1);
int n=strlen(s+1),now=0;
for(int i=1;i<=n;i++)
{
if(!ch[now][s[i]-'0']) ch[now][s[i]-'0']=++tot;
now=ch[now][s[i]-'0'];
}
endro[now]=1;
}
void build()
{
for(int i=0;i<10;i++)
if(ch[0][i])
q[++r]=ch[0][i];
while(l<=r)
{
int now=q[l++];
for(int i=0;i<10;i++)
{
if(ch[now][i]) fail[q[++r]=ch[now][i]]=ch[fail[now]][i];
else ch[now][i]=ch[fail[now]][i];
}
}
ch[0][0]=0;
}
int main()
{
scanf("%s",t+1);
int n=strlen(t+1),m;
for(int i=1;i<=n;i++) bit[i]=t[n+1-i]-'0';
scanf("%d",&m);
for(int i=1;i<=m;i++) ins();
build();
dp[n+1][0][1]=1;
for(int i=n+1;i>1;i--)
for(int j=0;j<=tot;j++)
for(int l=0;l<=1;l++)
for(int k=0,u=l?bit[i-1]:9;k<=u;k++)
{
int to=ch[j][k];
if(!endro[to]) add(dp[i-1][to][l&k==bit[i-1]],dp[i][j][l]);
}
int ans=mod-1;
for(int i=0;i<=tot;i++) add(ans,dp[1][i][0]),add(ans,dp[1][i][1]);
printf("%d\n",ans);
return 0;
}

2019.2.21

「SDOI2014」数数 解题报告的更多相关文章

  1. 「SDOI2014」向量集 解题报告

    「SDOI2014」向量集 维护一个向量集合,在线支持以下操作: A x y :加入向量 \((x, y)\): Q x y l r:询问第 \(L\) 个到第 \(R\) 个加入的向量与向量 \(( ...

  2. 「NOI2015」寿司晚宴 解题报告

    「NOI2015」寿司晚宴 这个题思路其实挺自然的,但是我太傻了...最开始想着钦定一些,结果发现假了.. 首先一个比较套路的事情是状压前8个质数,后面的只会在一个数出现一次的再想办法就好. 然后发现 ...

  3. 「ZJOI2016」大森林 解题报告

    「ZJOI2016」大森林 神仙题... 很显然线段树搞不了 考虑离线操作 我们只搞一颗树,从位置1一直往后移动,然后维护它的形态试试 显然操作0,1都可以拆成差分的形式,就是加入和删除 因为保证了操 ...

  4. 「SCOI2016」背单词 解题报告

    「SCOI2016」背单词 出题人sb 题意有毒 大概是告诉你,你给一堆n个单词安排顺序 如果当前位置为x 当前单词的后缀没在这堆单词出现过,代价x 这里的后缀是原意,但不算自己,举个例子比如abc的 ...

  5. 「SCOI2015」国旗计划 解题报告

    「SCOI2015」国旗计划 蛮有趣的一个题 注意到区间互不交错,那么如果我们已经钦定了一个区间,它选择的下一个区间是唯一的,就是和它有交且右端点在最右边的,这个可以单调队列预处理一下 然后往后面跳拿 ...

  6. 「JLOI2015」骗我呢 解题报告?

    「JLOI2015」骗我呢 这什么神仙题 \[\color{purple}{Link}\] 可以学到的东西 对越过直线的东西翻折进行容斥 之类的..吧? Code: #include <cstd ...

  7. 「JLOI2015」城池攻占 解题报告

    「JLOI2015」城池攻占 注意到任意两个人的战斗力相对大小的不变的 可以离线的把所有人赛到初始点的堆里 然后做启发式合并就可以了 Code: #include <cstdio> #in ...

  8. 「JLOI2015」管道连接 解题报告

    「JLOI2015」管道连接 先按照斯坦纳树求一个 然后合并成斯坦纳森林 直接枚举树的集合再dp一下就好了 Code: #include <cstdio> #include <cct ...

  9. 「JLOI2015」战争调度 解题报告

    「JLOI2015」战争调度 感觉一到晚上大脑就宕机了... 题目本身不难,就算没接触过想想也是可以想到的 这个满二叉树的深度很浅啊,每个点只会和它的\(n-1\)个祖先匹配啊 于是可以暴力枚举祖先链 ...

  10. 「SHOI2014」三叉神经树 解题报告

    「SHOI2014」三叉神经树 膜拜神仙思路 我们想做一个类似于动态dp的东西,首先得确保我们的运算有一个交换律,这样我们可以把一长串的运算转换成一块一块的放到矩阵上之类的东西,然后拿数据结构维护. ...

随机推荐

  1. 06_Hadoop分布式文件系统HDFS架构讲解

    mr  计算框架 假如有三台机器 统领者master 01  02  03  每台机器都有过滤的应用程序 移动数据 01机== 300M  >mr 移动计算  java程序传递给各个机器(mr) ...

  2. JEECG & JEESite Tomcat集群 Session共享

    多台tomcat服务的session共享 memcached与redis - JEECG开源社区 - CSDN博客https://blog.csdn.net/zhangdaiscott/article ...

  3. pip Read timed out 和 pip 源

    解决方法,设置超时时间 pip --default-timeout=100 install -U Pillow 安装时指定源(--index-url) #例如安装scipy时使用豆瓣的源 pip in ...

  4. C#设计模式之9:模板方法

    模板方法 模板方法是一个方法,定义了算法的步骤,并允许子类为一个或多个步骤提供实现. 本例中用冲泡咖啡和茶的例子来说明: 上图说明了冲泡咖啡和茶的步骤,可以看出冲泡咖啡和茶的步骤差不多,很相似,先来看 ...

  5. WPF中任务栏只显示主窗口

    我们在用WPF开发的时候,常常会遇到在主窗口打开的情况下,去显示子窗口,而此时任务栏同时显示主窗口与子窗口.这样看起来很不美观.所以在弹出子窗口之前,设置它的几个相应属性,便不会出现这种问题了. // ...

  6. CMake--静态库与动态库构建

    小结内容 建立一个静态库和动态库,提供 HelloFunc 函数供其他程序编程使用, HelloFunc 向终端输出Hello World 字符串. 安装头文件与共享库. 1.代码与CMakeList ...

  7. 当mysql报错1045时的解决方法

    2.用记事本打开 添加 打开后,搜索mysqld关键字 找到后,在mysqld下面添加skip-grant-tables,保存退出. 如果保存在了c盘里不能修改那么就采用这样的方法 然后就可以修改c盘 ...

  8. Prism框架研究(二)

    首先在介绍本节内容之前,首先来看看官方文档来如何描述Prism 应用的初始化吧!A Prism application requires registration and configuration ...

  9. 当应用程序不是以UserInteractive 模式运行时显示模式对话框或窗体

    最近在做一个WCF程序的时候,WCF程序老是弹出一个错误“当应用程序不是以UserInteractive 模式运行时显示模式对话框或窗体是无效操作.请指定ServiceNotification或Def ...

  10. query中对应的OnSetText和onGetText事件

    今天在看代码的时候遇到一个问题,query中的某个字段和在表中显示的不是一个值,我觉得很奇怪,于是找了很久,才知道为什么,原来是query中的OnSetText和onGetText事件在作怪,经过一番 ...