「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. PyCharm中快速给选中的代码加上{}、<>、()、[]

    快捷键Ctrl + Shift + S 呼出下图所示界面:

  2. Jenkins配置权限管理

    借鉴博客:https://www.cnblogs.com/Eivll0m/p/6734076.html 懒得写了,照上面是配置成功了,弄了权限角色与用户的配置

  3. linux安装httpd,做文件服务器

    在一个团队或者公司层面上,做一个本地的文件服务器,将网上的资源下载到本地,是有必要的.这将节省其他人的很多下载时间. >>提君博客原创  http://www.cnblogs.com/ti ...

  4. 剑指offer(17)层次遍历树

    题目: 从上往下打印出二叉树的每个节点,同层节点从左至右打印. public class Solution { ArrayList<Integer> list = new ArrayLis ...

  5. 记录SSM框架项目迁移SpringBoot框架-----pom.xml的迁移

    第一步:迁移pom.xml文件(去除spring相关的依赖) SSM中的pom: <project xmlns="http://maven.apache.org/POM/4.0.0&q ...

  6. Spring拦截器(学习笔记)

    SpringMVC 中的Interceptor 拦截请求是通过HandlerInterceptor 来实现的 在SpringMVC 中定义一个Interceptor 非常简单,主要有两种方式 第一种方 ...

  7. SpringBoot 标签之启动

    在SpringBoot中入口我们使用: package com.sankuai.qcs.regulation.traffic; import org.springframework.boot.Spri ...

  8. String 常见的十种方法!

    public class ZiFuChuan { public static void main(String[] args) { ZiFuChuanFangFa f=new ZiFuChuanFan ...

  9. loj6270

    #6270. 数据结构板子题 sol:对于一个询问L,R,Limit,答案就是所有长度小于R-l+1的线段-长度小于Limit的线段-左端点在L左边的线段-右端点在R右边的线段,求这个东西 后面两个东 ...

  10. Git——快速安装Git及初始化配置【二】

    文档 https://git-scm.com/book/zh/v2 下载 mac https://git-scm.com/download/mac Linux https://git-scm.com/ ...