【JZOJ3624】【SDOI2014】数数(count) AC自动机+数位dp
题面


100
容易想到使用AC自动机来处理禁忌子串的问题;
然后在自动机上数位dp,具体是:
\(f_{i,j,0/1}\)表示填了\(i\)位,当前在自动机的第\(j\)个结点上,\(0\)表示当前数已经小于了\(N\),\(1\)表示当前数等于\(N\)。
Code
#include<bits/stdc++.h>
#define ll long long
#define fo(i,x,y) for(int i=x;i<=y;i++)
#define fd(i,x,y) for(int i=x;i>=y;i--)
using namespace std;
const char* fin="ex3624.in";
const char* fout="ex3624.out";
const int inf=0x7fffffff;
const int maxn=1507,mo=1000000007;
struct node{
int x,fa,ne[10];
}ac[maxn];
int n,m,num=1,hd,tl=1;
int f[maxn][maxn][2],ne[maxn][10],b[maxn];
char a[maxn];
void makefail(){
while (hd++<tl){
int x=b[hd];
fo(i,0,9)
if (ac[x].ne[i]){
int y=ac[x].ne[i],z=ac[x].fa;
if (x){
while (z && !ac[z].ne[i]) z=ac[z].fa;
ac[y].fa=ac[z].ne[i];
}
b[++tl]=y;
ac[y].x+=ac[ac[y].fa].x;
}
}
}
int main(){
freopen(fin,"r",stdin);
freopen(fout,"w",stdout);
scanf("%s",a+1);
n=strlen(a+1);
scanf("%d",&m);
fo(i,1,m){
char ch=getchar();
int p=0;
while (ch<'0' || ch>'9') ch=getchar();
while (ch>='0' && ch<='9'){
int x=ch-'0';
if (!ac[p].ne[x]) ac[p].ne[x]=++num;
p=ac[p].ne[x];
ch=getchar();
}
ac[p].x++;
}
makefail();
fo(i,0,num){
if (i==1){
ne[1][0]=1;
fo(j,1,9) ne[1][j]=ne[0][j];
continue;
}
fo(j,0,9){
int x=ac[i].ne[j],y=ac[i].fa;
if (x){
if (ac[x].x) ne[i][j]=-1;
else ne[i][j]=x;
}else{
while (y && !ac[y].ne[j]) y=ac[y].fa;
if (ac[ac[y].ne[j]].x) ne[i][j]=-1;
else ne[i][j]=ac[y].ne[j];
}
}
}
memset(f,0,sizeof f);
f[0][1][0]=1;
fo(i,0,n-1)
fo(x,0,num){
fo(y,0,9){
if (ne[x][y]==-1) continue;
int z=ne[x][y],xc=a[i+1]-'0';
if (y<=xc){
if (y<xc) f[i+1][z][1]=(f[i+1][z][1]+f[i][x][0])%mo;
else f[i+1][z][0]=(f[i+1][z][0]+f[i][x][0])%mo;
}
f[i+1][z][1]=(f[i+1][z][1]+f[i][x][1])%mo;
}
}
int ans=0;
fo(x,0,num) ans=((ans+f[n][x][0])%mo+f[n][x][1])%mo;
ans--;
printf("%d",ans);
return 0;
}
【JZOJ3624】【SDOI2014】数数(count) AC自动机+数位dp的更多相关文章
- BZOJ 3530 [SDOI2014]数数 (Trie图/AC自动机+数位DP)
题目大意:略 裸的AC自动机+数位DP吧... 定义f[i][x][0/1]表示已经匹配到了第i位,当前位置是x,0表示没到上限,1到上限,此时数是数量 然而会出现虚拟前导零,即前几位没有数字的情况, ...
- 【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不是幸运 ...
- BZOJ 3530: [Sdoi2014]数数 [AC自动机 数位DP]
3530: [Sdoi2014]数数 题意:\(\le N\)的不含模式串的数字有多少个,\(n=|N| \le 1200\) 考虑数位DP 对于长度\(\le n\)的,普通套路DP\(g[i][j ...
- BZOJ3530:[SDOI2014]数数(AC自动机,数位DP)
Description 我们称一个正整数N是幸运数,当且仅当它的十进制表示中不包含数字串集合S中任意一个元素作为其子串.例如当S=(22,333,0233)时,233是幸运数,2333.20233.3 ...
- BZOJ3530[Sdoi2014]数数——AC自动机+数位DP
题目描述 我们称一个正整数N是幸运数,当且仅当它的十进制表示中不包含数字串集合S中任意一个元素作为其子串.例如当S=(22,333,0233)时,233是幸运数,2333.20233.3223不是幸运 ...
- [SDOI2014]数数 --- AC自动机 + 数位DP
[SDOI2014]数数 题目描述: 我们称一个正整数N是幸运数,当且仅当它的十进制表示中不包含数字串集合S中任意一个元素作为其子串. 例如当S=(22,333,0233)时,233是幸运数,2333 ...
- P3311 [SDOI2014]数数 AC自动机+数位DP
题意 给定一个正整数N和n个模式串,问不大于N的数字中有多少个不包含任意模式串,输出对\(1e^9+7\)取模后的答案. 解题思路 把所有模式串都加入AC自动机,然后跑数位DP就好了.需要注意的是,这 ...
- HDU-4518 吉哥系列故事——最终数 AC自动机+数位DP
题意:如果一个数中的某一段是长度大于2的菲波那契数,那么这个数就被定义为F数,前几个F数是13,21,34,55......将这些数字进行编号,a1 = 13, a2 = 21.现给定一个数n,输出和 ...
随机推荐
- 02_Spring Bean的装配模式_基于XML配置方式
一.三种实例化Bean的方式 1.使用类构造器实例化(默认无参数) <bean id="bean1" class="com.demo1.Bean1"> ...
- HBase Ambari
- window API GetProcessId OpenProcess
函数原型: DWORD WINAPI GetProcessId( _In_ HANDLE Process ); HANDLE OpenProcess( DWORD dwDesiredAccess, / ...
- List --搜索列表
1,常见的内建函数 . if val in L : # 是否在列表 . L.index(val) # 找下标 . L.count(val) # 有多少个 . min/max(L ) # 最大最小 . ...
- php冒泡算法
1.冒泡算法 网上搜了很多,但是总是对于每次循环的边界值思路讲的比较笼统. 不是很容易被新手记住,我自己平时也是硬记下来的. 但是对于算法,硬记,时间长了还是容易忘记,所以自己写了一次,把每次思路尽量 ...
- vbox搭建centos常用技巧
初始化 :vbox系统网络连接方式用桥接 :ping不通,请修改/etc/sysconfig/network-scripts/ifcfg-eth0 ONBOOT=no 改成 ONBOOT=yes 然后 ...
- c++ 读取8, 10, 16进制数
c++基础知识都快忘了..记一下 dec-十进制(默认) oct-八进制 hex-十六进制
- 创业型 APP 如何筛选合适的推送平台
对于中小型 App 开发团队来说,采用何种方式实现适时而精准的消息推送是一件矛盾的事.将相同内容推送给所有终端用户,担心打扰用户.引起用户反感:而个性化的分群推送,又因为团队人少.运营精力不足无法实现 ...
- webService学习五(插入片,---监控方法)
WS Explorer工具的使用: 1- web服务浏览器 2-将对应的路径copy到这里 - 3- 4-- 5-- 6--请求的数据: 7--相应数据 二.使用TCP/IP Monitor-拦截HT ...
- java代码乱序问题
java两个线程互相访问的时候并不能按照你的思路运行,因为执行语句可能有前后快慢之分,比如a=1和flag=true.下面线程B访问的时候 这两个赋值语句不一定按顺序执行 产生这种原因是因为指令重排序 ...