为什么我和同学对比了一下,发现我和他的做法差别很大啊

对于这种问题,我们把整个字符串分为两个部分:前缀顶着最高位和后缀没有顶着最高位。

我们枚举这个前缀,然后后缀通过 DP 来搞定。

不包含任何一个子串,似乎最有力的处理工具就是 ACAM。

于是我们可以确定这个 DP 的状态:\(dp[k][u]\) 表示从自动机的节点 \(u\) 上走 \(k\) 条边都遇不上被标记点的方案数。

转移:\(dp[k][u]\) 从 \(dp[k-1][trans[u][c]]\) 转移过来就好了。

但是这样会有一个问题:枚举出来的正整数含有前导 \(0\)。

考虑加上被判断成不合法的方案。我们枚举前导 \(0\) 的数量,然后将正整数分为四类:

//加前导0合法 / 不加前导0合法     - a
//加前导0合法 / 不加前导0不合法 - b=0
//加前导0不合法 / 不加前导0合法 - c
//加前导0不合法 / 不加前导0不合法 - d

可以发现我们原本计算的是 \(a+b\),但是我们需要计算 \(a+c\)。

枚举了前导 \(0\) 后,直接减去 \(a+b\) 然后加上 \(a+c\) 就可以了(

具体的话维护一个节点,每次都往 \(0\) 方向走就行了。

#include<cstring>
#include<cstdio>
#include<cctype>
typedef unsigned ui;
const ui M=1505,mod=1e9+7;
ui n,m,tot(1),dp[M][M],fail[M],trans[M][10];bool vis[M];char s[M],S[M];
inline void Insert(char*s){
ui u(1);
while(isdigit(*s)){
const ui&c=*s-48;*s++=0;
if(!trans[u][c])trans[u][c]=++tot;
u=trans[u][c];
}
vis[u]=true;
}
inline void Build(){
static ui L,R,q[M];L=1;
for(ui c=0;c<10;++c){
if(trans[1][c])q[++R]=trans[1][c],fail[trans[1][c]]=1;
else trans[1][c]=1;
}
while(L<=R){
const ui&u=q[L++];
for(ui c=0;c<10;++c){
if(trans[u][c])q[++R]=trans[u][c],fail[trans[u][c]]=trans[fail[u]][c];
else trans[u][c]=trans[fail[u]][c];
}
}
for(ui i=1;i<=R;++i)vis[q[i]]|=vis[fail[q[i]]];
}
signed main(){
ui ans(0);
scanf("%s%u",s+1,&n);m=strlen(s+1);
for(ui i=1;i<=n;++i){
scanf("%s",S);Insert(S);
}
Build();
for(ui u=1;u<=tot;++u)if(!vis[u])dp[0][u]=1;
for(ui i=1;i<=m;++i){
for(ui u=1;u<=tot;++u)if(!vis[u]){
for(ui c=0;c<10;++c)dp[i][u]=(dp[i][u]+dp[i-1][trans[u][c]])%mod;
}
}
ui u(1),now(1);
for(ui i=1;i<=m;++i){
if(vis[u])break;now=trans[now][0];
for(ui c=0;c<s[i]-48;++c)if(!vis[trans[u][c]])ans=(ans+dp[m-i][trans[u][c]])%mod;
if(i!=m)for(ui c=1;c<10;++c)ans=(ans+mod+dp[m-i-1][trans[1][c]]-dp[m-i-1][trans[now][c]])%mod;
u=trans[u][s[i]-48];
}
if(!vis[u])++ans,ans==mod&&(ans=0);
printf("%u",(ans+mod-1)%mod);
}

LGP3311题解的更多相关文章

  1. 2016 华南师大ACM校赛 SCNUCPC 非官方题解

    我要举报本次校赛出题人的消极出题!!! 官方题解请戳:http://3.scnuacm2015.sinaapp.com/?p=89(其实就是一堆代码没有题解) A. 树链剖分数据结构板题 题目大意:我 ...

  2. noip2016十连测题解

    以下代码为了阅读方便,省去以下头文件: #include <iostream> #include <stdio.h> #include <math.h> #incl ...

  3. BZOJ-2561-最小生成树 题解(最小割)

    2561: 最小生成树(题解) Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 1628  Solved: 786 传送门:http://www.lyd ...

  4. Codeforces Round #353 (Div. 2) ABCDE 题解 python

    Problems     # Name     A Infinite Sequence standard input/output 1 s, 256 MB    x3509 B Restoring P ...

  5. 哈尔滨理工大学ACM全国邀请赛(网络同步赛)题解

    题目链接 提交连接:http://acm-software.hrbust.edu.cn/problemset.php?page=5 1470-1482 只做出来四道比较水的题目,还需要加强中等题的训练 ...

  6. 2016ACM青岛区域赛题解

    A.Relic Discovery_hdu5982 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Jav ...

  7. poj1399 hoj1037 Direct Visibility 题解 (宽搜)

    http://poj.org/problem?id=1399 http://acm.hit.edu.cn/hoj/problem/view?id=1037 题意: 在一个最多200*200的minec ...

  8. 网络流n题 题解

    学会了网络流,就经常闲的没事儿刷网络流--于是乎来一发题解. 1. COGS2093 花园的守护之神 题意:给定一个带权无向图,问至少删除多少条边才能使得s-t最短路的长度变长. 用Dijkstra或 ...

  9. CF100965C题解..

    求方程 \[ \begin{array}\\ \sum_{i=1}^n x_i & \equiv & a_1 \pmod{p} \\ \sum_{i=1}^n x_i^2 & ...

随机推荐

  1. Redis 哨兵模式

    主从切换技术的方法是:当主服务器宕机了,需要手动将一台从服务器切换为主服务器,这就需要人工干预,这可能会造成一段时间的服务不可用. 一.哨兵模式的概述: 哨兵是一个独立的进程,作为一个进程,他会独立地 ...

  2. java常用类,包装类,String类的理解和创建对象以及StringBuilder和StringBuffer之间的区别联系

    一.包装类的分类: 1.黄色部分的父类为Number 继承关系: Boolean Character 其他六个基本数据类型 2.装箱和拆箱 理解:一个例子,其他的都相同 装箱:Integer inte ...

  3. LeetCode随缘刷题之截断句子

    这道题相对比较简单.正好最近学到StringBuilder就用了. package leetcode.day_12_06; /** * 句子 是一个单词列表,列表中的单词之间用单个空格隔开,且不存在前 ...

  4. 浅谈Java面向对象之抽象类(abstract)

    java语言,声明类时格式为: abstract class Db{} 说明Db类为抽象类.抽象方法是说没有方法的实现(方法体)此方法为抽象方法,只有抽象类和接口中才可以有抽象方法.简而言之,含有抽象 ...

  5. 基于XC7A100T的PCIe千兆电口以太网收发卡

    一.板卡概述 本板卡采用Xilinx公司的Artix7系列的XC7A100T-2FGG484 芯片作为主处理器.包含双路千兆电口网络,双组DDR,PCIeX1 V1.1接口,板卡设计满足工业级要求. ...

  6. C++的Copy Elision导致的奇怪问题

    最近写设计模式作业的时候, 有一个作业是实现装饰器模式 (Decorator Pattern), 由于我不会 Java, 所以只能用 C++ 来实现 在这个背景下, 会有简单(表意)的几个类, 如下: ...

  7. 我来教你如何将cpu使用率up起来(shell脚本[含注释])

    这个脚本是为了逃过一些资源检测的,当一些机器当前使用率偏低,会被客户要求收回,那咋办呢?使用下面的脚本,就可以留住你的机器了 假设要求cpu使用率不能低于35% 使用方法:bash up_up_up. ...

  8. pytest(12)-Allure常用特性allure.attach、allure.step、fixture、environment、categories

    上一篇文章pytest Allure生成测试报告我们学习了Allure中的一些特性,接下来继续学习其他常用的特性. allure.attach allure.attach用于在测试报告中添加附件,补充 ...

  9. Android SugarORM(4)

    Android Sugar ORM(4) Android Sugar ORM 数据库迁移 据官网描述, Sugar ORM的设计灵感来自与Rails(没用过, 咱也不知道是啥, 以后也许会学到吧)迁移 ...

  10. python中继承的语法及案列

    案例: 1 class Chinese: # 类的创建,类名首字母大写 2 eye = 'black' # 类属性的创建 3 4 def eat(self): # 实例方法创建 5 print('吃饭 ...