BZOJ3530:[SDOI2014]数数——题解
https://www.lydsy.com/JudgeOnline/problem.php?id=3530
我们称一个正整数N是幸运数,当且仅当它的十进制表示中不包含数字串集合S中任意一个元素作为其子串。例如当S=(22,333,0233)时,233是幸运数,2333、20233、3223不是幸运数。
给定N和S,计算不大于N的幸运数个数。
参考:https://www.luogu.org/blog/user17952/solution-p3311
绝对(对我来说)是道难题,尤其是很久不写AC自动机与数位dp的我……
首先n特别大,必须得考虑数位dp。
其次给了一堆串,要求不能出现这些串,先建AC自动机再说。
于是得出了一个愉快的结论:在AC自动机上跑数位dp(写到这里我只想用CaO来表达我的心情)
设$f[i][j][0/1]$为填到$i$数位,当前在AC自动机的$j$节点处,已经小于等于/大于到$i$位的原数。
此时需要注意:为了方便(因为参考是这么写的233),我们正着扫n而非以前的套路倒着扫n,这样做会带来一些问题,于是我们将小于等于也拆开,分别用0和1表示。
(PS:那么反着扫不知道是否可行……以及如果要反着扫的话可能需要反着存串。)
dp式子就不细讲了,直接看代码理解吧。唯一要注意的是不能有前导0所以第一层我们要特殊处理。
#include<map>
#include<cmath>
#include<stack>
#include<queue>
#include<cstdio>
#include<cctype>
#include<vector>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
typedef long long ll;
const int p=1e9+;
const int L=;
struct AC{
int fail,a[];
bool ed;
}tr[L];
char s[L],s0[L];
int tot,f[L][L][];
void insert(){
int len=strlen(s),now=;
for(int i=;i<len;i++){
int w=s[i]-'';
if(!tr[now].a[w])tr[now].a[w]=++tot;
now=tr[now].a[w];
}
tr[now].ed=;
}
void getfail(){
queue<int>q;
tr[].fail=;
for(int i=;i<;i++){
int u=tr[].a[i];
if(u){
tr[u].fail=;q.push(u);
}
}
while(!q.empty()){
int u=q.front();q.pop();
for(int i=;i<;i++){
if(tr[u].a[i]){
int v=tr[u].a[i];
tr[v].fail=tr[tr[u].fail].a[i];
tr[v].ed|=tr[tr[tr[u].fail].a[i]].ed;
q.push(v);
}else tr[u].a[i]=tr[tr[u].fail].a[i];
}
}
}
inline int add(int x,int y){
x+=y;if(x>=p)x-=p;return x;
}
int main(){
int n,m;
scanf("%s%d",s0,&m);
while(m--){
scanf("%s",s);insert();
}
getfail();
n=strlen(s0);
int ans=;
for(int i=;i<;i++){
int v=tr[].a[i],w=s0[]-'';
if(!tr[v].ed){
if(i<w)f[][v][]++;
else if(i==w)f[][v][]++;
else f[][v][]++;
}
}
for(int i=;i<n;i++){
int w=s0[i]-'';
for(int j=;j<=tot;j++){
if(f[i-][j][]||f[i-][j][]||f[i-][j][])
for(int k=;k<;k++){
int v=tr[j].a[k];
if(tr[v].ed)continue;
if(k<w){
f[i][v][]=add(f[i][v][],add(f[i-][j][],f[i-][j][]));
f[i][v][]=add(f[i][v][],f[i-][j][]);
}else if(k==w){
f[i][v][]=add(f[i][v][],f[i-][j][]);
f[i][v][]=add(f[i][v][],f[i-][j][]);
f[i][v][]=add(f[i][v][],f[i-][j][]);
}else{
f[i][v][]=add(f[i][v][],f[i-][j][]);
f[i][v][]=add(f[i][v][],add(f[i-][j][],f[i-][j][]));
}
}
}
}
for(int i=;i<n;i++){
for(int j=;j<=tot;j++){
ans=add(ans,add(f[i][j][],f[i][j][]));
if(i<n-)ans=add(ans,f[i][j][]);
}
}
printf("%d\n",ans);
return ;
}
+++++++++++++++++++++++++++++++++++++++++++
+本文作者:luyouqi233。 +
+欢迎访问我的博客:http://www.cnblogs.com/luyouqi233/ +
+++++++++++++++++++++++++++++++++++++++++++
BZOJ3530:[SDOI2014]数数——题解的更多相关文章
- BZOJ3530: [Sdoi2014]数数
3530: [Sdoi2014]数数 Time Limit: 10 Sec Memory Limit: 512 MBSubmit: 322 Solved: 188[Submit][Status] ...
- [bzoj3530][Sdoi2014]数数_AC自动机_数位dp
数数 bzoj-3530 Sdoi-2014 题目大意:给你一个整数集合,求所有不超过n的正整数,是的它的十进制表示下不能再一段等于集合中的任意数. 注释:$1\le n \le 1200$,$1\l ...
- 题解-[SDOI2014]数数
[SDOI2014]数数 这题的前置知识是AC自动机和dp,前置题目是 [JSOI2007]文本生成器,前置题目我写的题解 题解-[JSOI2007]文本生成器.我的讲解假设你做过上面那道题. 这题比 ...
- 【BZOJ3530】数数(AC自动机,动态规划)
[BZOJ3530]数数(AC自动机,动态规划) 题面 BZOJ 题解 很套路的\(AC\)自动机+\(DP\) 首先,如果长度小于\(N\) 就不存在任何限制 直接大力\(DP\) 然后强制限制不能 ...
- 【BZOJ】【3530】【SDOI2014】数数
AC自动机/数位DP orz zyf 好题啊= =同时加深了我对AC自动机(这个应该可以叫Trie图了吧……出边补全!)和数位DP的理解……不过不能自己写出来还真是弱…… /************* ...
- 【HDU3530】 [Sdoi2014]数数 (AC自动机+数位DP)
3530: [Sdoi2014]数数 Time Limit: 10 Sec Memory Limit: 512 MBSubmit: 682 Solved: 364 Description 我们称一 ...
- BZOJ 3530: [Sdoi2014]数数 [AC自动机 数位DP]
3530: [Sdoi2014]数数 题意:\(\le N\)的不含模式串的数字有多少个,\(n=|N| \le 1200\) 考虑数位DP 对于长度\(\le n\)的,普通套路DP\(g[i][j ...
- C#版 - Leetcode 633. 平方数之和 - 题解
版权声明: 本文为博主Bravo Yeung(知乎UserName同名)的原创文章,欲转载请先私信获博主允许,转载时请附上网址 http://blog.csdn.net/lzuacm. C#版 - L ...
- 「SDOI2014」数数 解题报告
「SDOI2014」数数 题目描述 我们称一个正整数 \(N\) 是幸运数,当且仅当它的十进制表示中不包含数字串集合 \(S\) 中任意一个元素作为其子串. 例如当 \(S=(\)22, 333, 0 ...
- 3530: [Sdoi2014]数数
3530: [Sdoi2014]数数 链接 分析: 对给定的串建立AC自动机,然后数位dp.数位dp的过程中,记录当前在AC自动机的哪个点上,保证不能走到出现了给定串的点. 代码: #include& ...
随机推荐
- 【转】linux下,如何把整个文件夹上传到服务器(另一台linux)
原文转自:https://zhidao.baidu.com/question/1046040541327493019.html 1.Linux下目录复制:本机->远程服务器 scp -r /h ...
- Spring Cloud搭建微服务架构----文章汇总
Spring Cloud搭建微服务架构----前言 原文地址:https://my.oschina.net/u/1000241/blog/882929 Spring Cloud搭建微服务架构----使 ...
- 简析Monte Carlo与TD算法的相关问题
Monte Carlo算法是否能够做到一步更新,即在线学习? 答案显然是不能,如果可以的话,TD算法还有何存在的意义?MC算法必须要等到episode结束后才可以进行值估计的主要原因在于对Return ...
- 剑指Offer66题的总结、目录
原文链接 剑指Offer每日6题系列终于在今天全部完成了,从2017年12月27日到2018年2月27日,历时两个月的写作,其中绝大部分的时间不是花在做题上,而是花在写作上,这个系列不适合大神,大牛, ...
- Heavy Cargo POJ 2263 (Floyd传递闭包)
Description Big Johnsson Trucks Inc. is a company specialized in manufacturing big trucks. Their lat ...
- linux awk,sort,uniq,wc,cut命令详解
1.awk awk是行处理器: 相比较屏幕处理的优点,在处理庞大文件时不会出现内存溢出或是处理缓慢的问题,通常用来格式化文本信息 $ 表示当前行 $ 表示第一列 NF 表示一共有多少列 $NF 表示最 ...
- resx文件引用
应用场景: 自己在编写双语界面的时候,用到两种语言表. 引用如下: LocRM = new ResourceManager("TMI_E.words_" + lang.ToLowe ...
- ASP.NET MVC5 学习系列之模型绑定
一.理解 Model Binding Model Binding(模型绑定) 是 HTTP 请求和 Action 方法之间的桥梁,它根据 Action 方法中的 Model 类型创建 .NET 对象, ...
- CSU 1808: 地铁 最短路
题目链接: http://acm.csu.edu.cn/OnlineJudge/problem.php?id=1808 1808: 地铁 Time Limit: 5 SecMemory Limit: ...
- alpha冲6
队名:日不落战队 安琪(队长) 今天完成的任务 回收站前端界面. 明天的计划 查看个人信息界面. 还剩下的任务 信息修改前端界面. 设置界面. 遇到的困难 模拟机莫名其妙就崩了,调试了很久,后在队友的 ...