题目

把\(s\)串所有长度为\(\lfloor \frac{d}{2}\rfloor\)的子串插入一个ACAM中,之后数位dp就好了,状态是\(dp_{i,j,0/1}\)第\(i\)位,在ACAM上的节点\(j\),不卡/卡上界;正难则反一下,统计所有不能被表示即没有经过结束标记的路径即可

注意前导0的处理

代码

#include<bits/stdc++.h>
#define re register
#define LL long long
const int mod=1e9+7;
char S[1005],A[55],B[55];int d;
int fa[1005*50],son[1005*50][10],f[1005*50],cnt;
int dp[2][1005*25][2],n,lm[55];
inline int dqm(int x) {return x<0?x+mod:x;}
inline int qm(int x) {return x>=mod?x-mod:x;}
inline void ins(int l,int r) {
int nw=0;
for(re int i=l;i<=r;++i) {
if(!son[nw][S[i]-'0']) son[nw][S[i]-'0']=++cnt;
nw=son[nw][S[i]-'0'];
}
f[nw]=1;
}
inline int solve(char *H) {
int ans=0;
for(re int i=1;i<=d;i++) lm[i]=H[d-i+1]-'0';
for(re int i=d;i;i--) ans=10ll*ans%mod,ans=qm(ans+lm[i]);
int o=0;memset(dp,0,sizeof(dp));dp[0][0][1]=1;
for(re int i=d;i;--i,o^=1) {
memset(dp[o^1],0,sizeof(dp[o^1]));
for(re int j=0;j<=cnt;++j) {
if(!dp[o][j][0]) continue;
for(re int k=0;k<=9;++k) {
if(f[son[j][k]]) continue;
dp[o^1][son[j][k]][0]=qm(dp[o^1][son[j][k]][0]+dp[o][j][0]);
}
}
for(re int j=0;j<=cnt;++j) {
if(!dp[o][j][1]) continue;
for(re int k=0;k<lm[i];++k) {
if(f[son[j][k]]) continue;
dp[o^1][son[j][k]][0]=qm(dp[o^1][son[j][k]][0]+dp[o][j][1]);
}
if(!f[son[j][lm[i]]])
dp[o^1][son[j][lm[i]]][1]=qm(dp[o^1][son[j][lm[i]]][1]+dp[o][j][1]);
}
if(i==d&&!f[son[0][0]]) dp[o^1][son[0][0]][0]=dqm(dp[o^1][son[0][0]][0]-1);
if(i!=d) {
for(re int j=1;j<=9;j++) {
if(f[son[0][j]]) continue;
dp[o^1][son[0][j]][0]=qm(dp[o^1][son[0][j]][0]+1);
}
}
}
for(re int i=0;i<=cnt;i++) ans=dqm(ans-dp[o][i][0]),ans=dqm(ans-dp[o][i][1]);
return ans;
}
inline int chk(char *H) {
int nw=0;
for(re int i=1;i<=d;i++) {nw=son[nw][H[i]-'0'];if(f[nw]) return 1;}
return 0;
}
int main() {
scanf("%s",S+1);n=strlen(S+1);scanf("%s",A+1);scanf("%s",B+1);d=strlen(A+1);
for(re int i=1;i+(d>>1)-1<=n;i++) ins(i,i+(d>>1)-1);
std::queue<int> q;
for(re int i=0;i<=9;i++) if(son[0][i]) q.push(son[0][i]);
while(!q.empty()) {
int k=q.front();q.pop();f[k]|=f[fa[k]];
for(re int i=0;i<=9;i++)
if(son[k][i])fa[son[k][i]]=son[fa[k]][i],q.push(son[k][i]);else son[k][i]=son[fa[k]][i];
}
printf("%d\n",(solve(B)-solve(A)+mod+chk(A))%mod);
return 0;
}

最新文章

  1. SQL 提示介绍 hash/merge/concat union
  2. 多线程IP获取工具(C#)
  3. 使用js实现点击按钮下载文件
  4. FusionCharts简单教程(七)-----使用FusionCharts实现下钻功能
  5. SQL LOADER 的用法 TXT文件导入非常之快
  6. 鼠标点击输入框文字消失 value placeholder 以及JQ实现效果 (仿京东的输入框效果)
  7. PHP批量过滤MYSQL数据库内站外链接和图片
  8. Hololens开发笔记之Gesture手势识别(手势检测反馈)
  9. Linux 性能监控、测试、优化工具
  10. main函数参数的使用
  11. effective c++(04)之对象使用前初始化
  12. OpenGL中glFrustum()和gluPerspective()的相互转换
  13. linux 邮件服务器
  14. mac效率工具
  15. react和vue的不同
  16. Jmeter进阶篇之保存测试结果
  17. Miscellaneos:ISV
  18. electron 前端开发桌面应用
  19. 静态代码检查findbugs/阿里巴巴开发规范
  20. 通过runtime打印出对象所有属性的值

热门文章

  1. Scrapy框架: 通用爬虫之CSVFeedSpider
  2. SpringBoot-技术专区-配置文件加密
  3. JavaScript 事件——“模拟事件”的注意要点
  4. 利用Swiperefreshlayout实现下拉刷新功能的技术探讨
  5. 2019-8-31-C#-使用汇编
  6. jenkins发送邮箱配置,出现Error sending to the following VALID addresses,解决方案
  7. oracle死锁查询
  8. VS2013+phread.h环境配置
  9. Java多线程状态切换
  10. QUIC协议学习记录