阿拉~好像最近总是做到 AC 自动机的题目呢喵~

题目的算法似乎马上就能猜到的样子…… AC 自动机 + 数位 dp

先暴力转移出 f[i][j] :表示从 AC 自动机上第 j 号节点走 i 步且不碰到匹配串的方案数

然后直接用数位 dp 一位一位的试就可以了,大家都会吧~

但是…… 有前导 0 的情况真尼玛蛋疼啊!

忽的灵光一闪……

前导 0 仅能影响长度小于 L 的数的统计

那么所有长度 <L 的数全部专门暴力统计一边不就可以了!我真是特么太机智了喵~ O(∩_∩)O~

虽然有个 O(10*L*l) 的转移 但是只跑了 272 ms 呢

 #include <cstdio>
#include <cstring>
#define ord(ch) ((ch)-'0')
const int sizeOfLength=;
const int sizeOfNumber=;
const int sizeOfType=;
const int mod=; struct node
{
int idx;
bool end;
node * fail, * ch[sizeOfType];
};
node * dfa;
node memory[sizeOfNumber], * port=memory;
inline node * newnode();
inline void insert(char * , int);
node * q[sizeOfNumber]; int l, r;
inline void build();
inline void dynamicprogramming(); char N[sizeOfLength]; int L;
int M;
int f[sizeOfLength][sizeOfNumber];
char s[sizeOfNumber]; int len;
inline int getint();
inline int getstr(char * );
inline void putint(int); int main()
{
int ans=;
bool find=true;
node * t; L=getstr(N);
M=getint();
dfa=newnode();
for (int i=;i<=M;i++)
{
len=getstr(s);
insert(s, len);
}
build();
dynamicprogramming(); t=dfa;
for (int i=;i<L;i++)
{
for (int j=(i==);j<ord(N[i]);j++) if (!t->ch[j]->end)
ans=(ans+f[L-i-][t->ch[j]->idx])%mod;
t=t->ch[ord(N[i])];
if (t->end)
{
find=false;
break;
}
}
for (int i=L-;i>=;i--)
for (int j=;j<=;j++)
ans=(ans+f[i][dfa->ch[j]->idx])%mod; putint(ans+find); return ;
}
inline int getint()
{
register int num=;
register char ch;
do ch=getchar(); while (ch<'' || ch>'');
do num=num*+ch-'', ch=getchar(); while (ch>='' && ch<='');
return num;
}
inline int getstr(char * str)
{
register int len=;
register char ch;
do ch=getchar(); while (ch<'' || ch>'');
do str[len++]=ch, ch=getchar(); while (ch>='' && ch<='');
return len;
}
inline void putint(int num)
{
char stack[];
register int top=;
for ( ;num;num/=) stack[++top]=num%+'';
for ( ;top;top--) putchar(stack[top]);
putchar('\n');
}
inline node * newnode()
{
node * ret=port++;
ret->idx=port-memory-;
ret->fail=NULL;
memset(ret->ch, , sizeof ret->ch);
return ret;
}
inline void insert(char * s, int l)
{
node * t=dfa;
for (int i=;i<l;i++)
{
if (!t->ch[ord(s[i])]) t->ch[ord(s[i])]=newnode();
t=t->ch[ord(s[i])];
}
t->end=true;
}
inline void build()
{
dfa->fail=dfa;
for (int i=;i<sizeOfType;i++)
if (dfa->ch[i])
{
dfa->ch[i]->fail=dfa;
q[r++]=dfa->ch[i];
}
else
dfa->ch[i]=dfa;
for ( ;l<r;l++)
{
node * u=q[l];
u->end|=u->fail->end;
for (int i=;i<sizeOfType;i++)
if (u->ch[i])
{
u->ch[i]->fail=u->fail->ch[i];
q[r++]=u->ch[i];
}
else
u->ch[i]=u->fail->ch[i];
}
}
inline void dynamicprogramming()
{
int tot=port-memory;
for (int i=;i<tot;i++)
if (!(dfa+i)->end)
f[][(dfa+i)->idx]=;
for (int i=;i<=L;i++)
for (int j=;j<tot;j++) if (!(dfa+j)->end)
for (int k=;k<sizeOfType;k++)
f[i][(dfa+j)->idx]=(f[i][(dfa+j)->idx]+f[i-][(dfa+j)->ch[k]->idx])%mod;
}

机房不卡代码插入了 好评如潮

[BZOJ 3530][Sdoi 2014]数数的更多相关文章

  1. 【BZOJ 3530】【SDOI 2014】数数

    http://www.lydsy.com/JudgeOnline/problem.php?id=3530 上午gty的测试题,爆0了qwq 类似文本生成器那道题,把AC自动机的转移建出来,准确地说建出 ...

  2. BZOJ 3533 sdoi 2014 向量集

    设(x,y)为Q的查询点,分类讨论如下:1.y>0:  最大化a*x+b*y,维护一个上凸壳三分即可 2.y<0:最大化a*x+b*y  维护一个下凸壳三分即可 我们考虑对时间建出一棵线段 ...

  3. 【BZOJ】【3530】【SDOI2014】数数

    AC自动机/数位DP orz zyf 好题啊= =同时加深了我对AC自动机(这个应该可以叫Trie图了吧……出边补全!)和数位DP的理解……不过不能自己写出来还真是弱…… /************* ...

  4. BZOJ 3530: [Sdoi2014]数数 [AC自动机 数位DP]

    3530: [Sdoi2014]数数 题意:\(\le N\)的不含模式串的数字有多少个,\(n=|N| \le 1200\) 考虑数位DP 对于长度\(\le n\)的,普通套路DP\(g[i][j ...

  5. [BZOJ 3530] [Sdoi2014] 数数 【AC自动机+DP】

    题目链接:BZOJ - 3530 题目分析 明显是 AC自动机+DP,外加数位统计. WZY 神犇出的良心省选题,然而去年我太弱..比现在还要弱得多.. 其实现在做这道题,我自己也没想出完整解法.. ...

  6. bzoj 3530: [Sdoi2014]数数 数位dp

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

  7. 3530: [Sdoi2014]数数

    3530: [Sdoi2014]数数 链接 分析: 对给定的串建立AC自动机,然后数位dp.数位dp的过程中,记录当前在AC自动机的哪个点上,保证不能走到出现了给定串的点. 代码: #include& ...

  8. [BZOJ 3930] [CQOI 2015]选数(莫比乌斯反演+杜教筛)

    [BZOJ 3930] [CQOI 2015]选数(莫比乌斯反演+杜教筛) 题面 我们知道,从区间\([L,R]\)(L和R为整数)中选取N个整数,总共有\((R-L+1)^N\)种方案.求最大公约数 ...

  9. 【BZOJ 3326】[Scoi2013]数数

    题目描述 Fish 是一条生活在海里的鱼,有一天他很无聊,就开始数数玩.他数数玩的具体规则是: 确定数数的进制B 确定一个数数的区间[L, R] 对于[L, R] 间的每一个数,把该数视为一个字符串, ...

随机推荐

  1. Hibernate <一级缓存>

    Hibernate缓存分为三级: 一级缓存:基于事务级别(内存)的缓存,也可以成为session级别缓存 二级缓存:依赖于第三方,当请求一个对象时,先在缓存里面查找,如果没有就执行查询语句 查询缓存: ...

  2. 使用 Jasmine 进行测试驱动的 JavaScript 开发

    Jasmine 为 JavaScript 提供了 TDD (测试驱动开发)的框架,对于前端软件开发提供了良好的质量保证,这里对 Jasmine 的配置和使用做一个说明. 目前,Jasmine 的最新版 ...

  3. CAD字体显示问号的解决办法

    CAD字体显示问号的解决办法1.选中问号的文字,ctrl+1查看下文字样式,以standard为例.2.运行st命令,设置standard样式的字体名为windows自带的ttf字体,例如宋体或者仿宋 ...

  4. 能源项目xml文件 -- app-dubbo.xml

    <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.sp ...

  5. 51nod 1158 全是1的最大子矩阵

    题目链接:51nod 1158 全是1的最大子矩阵 题目分类是单调栈,我这里直接用与解最大子矩阵类似的办法水过了... #include<cstdio> #include<cstri ...

  6. C#窗体 WinForm 进程,线程

    一.进程 进程是一个具有独立功能的程序关于某个数据集合的一次运行活动. 它可以申请和拥有系统资源,是一个动态的概念,是一个活动的实体. Process 类,用来操作进程. 命名空间:using Sys ...

  7. freemarker if elseif

    FreeMarker模板 if, else, elseif 指令 : if, else, elseif 语法 <#if condition> ... <#elseif conditi ...

  8. Java:集合工具类-Collections

    Java.util.Collections 集合框架工具类Collections,其方法都是静态的,本身没有构造函数. 常见方法: static <T extends Comparable< ...

  9. Android APK反编译就这么简单 详解(附图)

    在学习Android开发的过程你,你往往会去借鉴别人的应用是怎么开发的,那些漂亮的动画和精致的布局可能会让你爱不释手,作为一个开发者,你可能会很想知道这些效果界面是怎么去实现的,这时,你便可以对改应用 ...

  10. Node.js GET/POST请求

    在很多场景中,我们的服务器都需要跟用户的浏览器打交道,如表单提交. 表单提交到服务器一般都使用GET/POST请求. 我将为大家介绍 Node.js GET/POST请求. 获取GET请求内容 由于G ...