BZOJ 3530 [SDOI2014]数数 (Trie图/AC自动机+数位DP)
题目大意:略
裸的AC自动机+数位DP吧...
定义f[i][x][0/1]表示已经匹配到了第i位,当前位置是x,0表示没到上限,1到上限,此时数是数量
然而会出现虚拟前导零,即前几位没有数字的情况,实际上是在0号节点原地打转,所以多加一维状态,再额外讨论第1位就行了
#include <cmath>
#include <queue>
#include <vector>
#include <cstdio>
#include <cstring>
#include <algorithm>
#define NN 1210
#define MM 1510
#define ll long long
#define dd double
#define uint unsigned int
#define mod 1000000007
#define idx(X) (X-'0')
#define eps (1e-9)
using namespace std; int n,m,cte;
int head[NN];
struct Edge{int to,nxt;}edge[NN*];
void ae(int u,int v){
cte++;edge[cte].nxt=head[u];
head[u]=cte,edge[cte].to=v;
}
uint f[NN][MM][];
int ma[NN]; namespace AC{
int ch[NN][],fail[NN],tot,ed[NN];
void Build_Trie(char *str,int len)
{
int x=;
for(int i=;i<=len;i++){
if(!ch[x][idx(str[i])])
ch[x][idx(str[i])]=++tot;
x=ch[x][idx(str[i])];
}ed[x]=;
}
void Build_Fail()
{
queue<int>q;
for(int i=;i<=;i++)
if(ch[][i]) q.push(ch[][i]);
while(!q.empty())
{
int x=q.front();q.pop();
ae(fail[x],x);
for(int i=;i<=;i++)
{
if(ch[x][i]){
fail[ch[x][i]]=ch[fail[x]][i];
q.push(ch[x][i]);
}else{
ch[x][i]=ch[fail[x]][i];
}
}
}
q.push();
while(!q.empty())
{
int x=q.front();q.pop();
for(int j=head[x];j;j=edge[j].nxt){
int v=edge[j].to;
ed[v]|=ed[x];
q.push(v);
}
}
}
void solve()
{
f[][][]++;
for(int j=;j<ma[];j++){
if(!ed[ch[][j]])
f[][ch[][j]][]++;}
if(!ed[ch[][ma[]]])
f[][ch[][ma[]]][]++;
for(int i=;i<n;i++)
{
f[i+][][]=;
int x=;
//nolimited
for(int j=;j<=;j++){
if(!ed[ch[x][j]])
(f[i+][ch[x][j]][]+=f[i][x][]+((j!=)?f[i][x][]:))%=mod;
}
//limited
for(int j=;j<ma[i+];j++)
if(!ed[ch[x][j]])
(f[i+][ch[x][j]][]+=f[i][x][])%=mod;
if(!ed[ch[x][ma[i+]]])
(f[i+][ch[x][ma[i+]]][]+=f[i][x][])%=mod;
for(x=;x<=tot;x++)
{
//nolimited
for(int j=;j<=;j++){
if(!ed[ch[x][j]])
(f[i+][ch[x][j]][]+=f[i][x][])%=mod;
}
//limited
for(int j=;j<ma[i+];j++)
if(!ed[ch[x][j]])
(f[i+][ch[x][j]][]+=f[i][x][])%=mod;
if(!ed[ch[x][ma[i+]]])
(f[i+][ch[x][ma[i+]]][]+=f[i][x][])%=mod;
//(f[i+1][ch[x][0]][2]+=f[i][x][2])%=mod;
}
}
uint ans=;
for(int x=;x<=tot;x++)
(ans+=f[n][x][]+f[n][x][])%=mod;
printf("%u\n",ans);
}
};
char str[NN]; int main()
{
//freopen("t1.in","r",stdin);
scanf("%s",str+);
n=strlen(str+);
for(int i=;i<=n;i++)
ma[i]=idx(str[i]);
scanf("%d",&m);
for(int i=;i<=m;i++){
scanf("%s",str+);
int len=strlen(str+);
AC::Build_Trie(str,len);
}AC::Build_Fail();
AC::solve();
return ;
}
BZOJ 3530 [SDOI2014]数数 (Trie图/AC自动机+数位DP)的更多相关文章
- 【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不是幸运 ...
- HDU-4518 吉哥系列故事——最终数 AC自动机+数位DP
题意:如果一个数中的某一段是长度大于2的菲波那契数,那么这个数就被定义为F数,前几个F数是13,21,34,55......将这些数字进行编号,a1 = 13, a2 = 21.现给定一个数n,输出和 ...
- zoj3494BCD Code(ac自动机+数位dp)
l链接 这题想了好一会呢..刚开始想错了,以为用自动机预处理出k长度可以包含的合法的数的个数,然后再数位dp一下就行了,写到一半发现不对,还要处理当前走的时候是不是为合法的,这一点无法移到trie树上 ...
- BZOJ 3530: [Sdoi2014]数数 [AC自动机 数位DP]
3530: [Sdoi2014]数数 题意:\(\le N\)的不含模式串的数字有多少个,\(n=|N| \le 1200\) 考虑数位DP 对于长度\(\le n\)的,普通套路DP\(g[i][j ...
- BZOJ3530[Sdoi2014]数数——AC自动机+数位DP
题目描述 我们称一个正整数N是幸运数,当且仅当它的十进制表示中不包含数字串集合S中任意一个元素作为其子串.例如当S=(22,333,0233)时,233是幸运数,2333.20233.3223不是幸运 ...
- BZOJ3530:[SDOI2014]数数(AC自动机,数位DP)
Description 我们称一个正整数N是幸运数,当且仅当它的十进制表示中不包含数字串集合S中任意一个元素作为其子串.例如当S=(22,333,0233)时,233是幸运数,2333.20233.3 ...
- [SDOI2014]数数 --- AC自动机 + 数位DP
[SDOI2014]数数 题目描述: 我们称一个正整数N是幸运数,当且仅当它的十进制表示中不包含数字串集合S中任意一个元素作为其子串. 例如当S=(22,333,0233)时,233是幸运数,2333 ...
- BZOJ 1444 [JSOI2009]有趣的游戏 (Trie图/AC自动机+矩阵求逆)
题目大意:给你$N$个长度相等且互不相同的模式串,现在有一个字符串生成器会不断生成字符,其中每个字符出现的概率是$p_{i}/q_{i}$,当生成器生成的字符串包含了某个模式串,则拥有该模式串的玩家胜 ...
随机推荐
- Mysql-slowlog
MySQL慢查询日志是MySQL提供的一种日志记录,用来记录执行时长超过指定时长的查询语句,具体指运行时间超过 long_query_time 值的 SQL 语句,则会被记录到慢查询日志中. long ...
- Kattis - CD
CD Jack and Jill have decided to sell some of their Compact Discs, while they still have some value. ...
- css——overflow
Overflow:属性规定当前内容溢出元素框时发生的事情 1.当内容过多,元素框溢出 1)hidden:隐藏超出部分(overflow: hidden;) 2)auto:有下拉滚动条(overflow ...
- HDU 2049 不容易系列之(4)——考新郎( 错排 )
链接:传送门 思路:错排水题,从N个人中选出M个人进行错排,即 C(n,m)*d[m] 补充:组合数C(n,m)能用double计算吗?第二部分有解释 Part 1. 分别求出来组合数的分子和分母然后 ...
- linux内核(二)内核移植(DM365-DM368开发攻略——linux-2.6.32的移植)
一.介绍linux-2.6.32: Linux-2.6.32的网上介绍:增添了虚拟化内存 de-duplicacion.重写了 writeback 代码.改进了 Btrfs 文件系统.添加了 ATI ...
- PatentTips - Object-oriented processor architecture and operating method
BACKGROUND OF THE INVENTION The present invention relates to processors and computer systems. More s ...
- ssm框架下上传图片及其他信息
先引入这两个包: <dependency> <groupId>commons-fileupload</groupId> <artifactId>comm ...
- 【转载】How to Reset USB Device in Linux
USB devices are anywhere nowadays, even many embedded devices replace the traditional serial devices ...
- [ReactVR] Render Custom 3D Objects Using the Model Component in React VR
React VR isn't limited to simple 3D primitives. By using the <Model/> Component we can place a ...
- 个人andriod实习小作品,个人联网笔记本
个人联网笔记本 个人信息:就读于燕大本科软件project专业 眼下大四; 本人博客:google搜索"cqs_2012"就可以; 个人爱好:酷爱数据结构和算法,希望将来从事算法工 ...