【JZOJ5332】【NOIP2017提高A组模拟8.23】密码
2017-08-23 22:50
639 查看
Description
Data Constraint
Solution
考场上没想到挺可惜的,明明以前做过两次的~我们将正整数放到一个AC自动机上跑。做一个数位dp,设f[i][j][k][0..1]表示当前到第i位,在自动机上节点j包含k个秘钥,前i位是否与上界相同的方案。我们每次枚举下一位放的数字,看一下AC自动机会跳至哪里转移一下。复杂度O(S*s*k*10)。
Code
#include<iostream> #include<cmath> #include<cstring> #include<cstdio> #include<algorithm> #define ll long long using namespace std; const ll maxn=505,mo=1e9+7; ll f[maxn][10],g[maxn][205][11][2],d[maxn],fa[maxn],v[maxn],a[maxn],mi[maxn],b[maxn]; ll n,m,i,t,j,k,l,x,y,z,num,ans; char s[maxn],s1[maxn],s2[maxn]; void bfs(){ int i=0,j=1,x,k; while (i<j){ x=v[++i]; for (k=0;k<10;k++){ if (!f[x][k]) continue; y=fa[x]; while (!f[y][k] && y) y=fa[y]; v[++j]=f[x][k];if (f[y][k]!=f[x][k])fa[v[j]]=f[y][k]; d[v[j]]+=d[fa[v[j]]]; } } } ll dg(){ memset(g,0,sizeof(g)); ll i,j,k,l,x,y=0;b[a[0]+1]=1; for (i=a[0];i>=1;i--) b[i]=(b[i+1]+mi[a[0]-i]*a[i]%mo)%mo; g[0][0][0][1]=1; for (i=0;i<=a[0];i++) for (j=0;j<=num;j++){ for (k=0;k<m;k++){ if (i==a[0]) break; if (g[i][j][k][0]){ for (l=0;l<=9;l++){x=j; while (!f[x][l] && x) x=fa[x]; if (f[x][l]) x=f[x][l]; g[i+1][x][min(m,k+d[x])][0]=(g[i][j][k][0]+g[i+1][x][min(m,k+d[x])][0])%mo; } } if (g[i][j][k][1]){ for (l=0;l<a[i+1];l++){x=j; while (!f[x][l] && x) x=fa[x]; if (f[x][l]) x=f[x][l]; g[i+1][x][min(m,k+d[x])][0]=(g[i][j][k][1]+g[i+1][x][min(m,k+d[x])][0])%mo; } x=j; while (!f[x][l] && x) x=fa[x]; if (f[x][l]) x=f[x][l]; g[i+1][x][min(m,k+d[x])][1]=(g[i][j][k][1]+g[i+1][x][min(m,k+d[x])][1])%mo; } } y=(y+g[i][j][m][0]*mi[a[0]-i]%mo)%mo; y=(y+g[i][j][m][1]*b[i+1]%mo)%mo; } return y; } int main(){ freopen("word.in","r",stdin);freopen("word.out","w",stdout); scanf("%lld%lld",&n,&m); scanf("%s%s\n",s+1,s1+1);t=strlen(s+1);mi[0]=1; for (i=1;i<=500;i++)mi[i]=mi[i-1]*10%mo; for (i=1;i<=t;i++)a[i]=s[i]-48;a[0]=t; for (i=1;i<=n;i++){ x=0; scanf("%s\n",s2+1);t=strlen(s2+1); for (j=1;j<=t;j++){ if (!f[x][s2[j]-48]) f[x][s2[j]-48]=++num; x=f[x][s2[j]-48]; } d[x]++; } bfs(); ans=-dg();t=strlen(s1+1); for (i=1;i<=t;i++)a[i]=s1[i]-48;a[0]=t; ans=(ans+dg()+mo)%mo; printf("%lld\n",ans); }
相关文章推荐
- 【jzoj5332】【NOIP2017提高A组模拟8.23】【密码】【ac自动机】【动态规划】
- 5332. 【NOIP2017提高A组模拟8.23】密码 AC自动机+数位DP
- jzoj5330 【NOIP2017提高A组模拟8.22】密码
- 【jzoj5333】【NOIP2017提高A组模拟8.23】【大新闻】【可持久化线段树】
- jzoj5331 【NOIP2017提高A组模拟8.23】壕游戏
- 【JZOJ5330】【NOIP2017提高A组模拟8.22】密码【51nod1569】二项式系数的个数
- jzoj. 100031. 【NOIP2017提高A组模拟7.9】外星密码
- 【jzoj5315】【NOIP2017提高A组模拟8.19】【小串串】【sam 】
- jzoj5385. 【NOIP2017提高A组模拟9.23】Carry
- 【JZOJ5335】【NOIP2017提高A组模拟8.24】早苗
- 【JZOJ 5393】【NOIP2017提高A组模拟10.5】Snake vs Block
- JZOJ 5400. 【NOIP2017提高A组模拟10.7】Repulsed
- JZOJ 5177. 【NOIP2017提高组模拟6.28】TRAVEL
- JZOJ 5183. 【NOIP2017提高组模拟6.29】小T的钢琴
- JZOJ 5186. 【NOIP2017提高组模拟6.30】tty's home
- JZOJ 5406. 【NOIP2017提高A组模拟10.10】Tree
- JZOJ 5403. 【NOIP2017提高A组模拟10.8】Lost My Music
- JZOJ5405. 【NOIP2017提高A组模拟10.10】Permutation
- JZOJ 100026. 【NOIP2017提高A组模拟7.7】图
- 【jzoj5248】【NOIP2017提高A组模拟8.10】【花花的聚会】【动态规划】【可持久化线段树】