• 题意:问有多少个<=n(\(10^{1201}\))的数满足下面所给的模式串没有在其中出现过
  • 思路:首先一堆串没在构造的串中,套路就是AC自动机上dp,不经过cnt[]>0的点。
    不过<=n怎么做呢?从n范围容易想到数位dp。
    不过有一种更巧妙的方法:
    首先位数<n,每位没有限制
    (类似康托展开:每次讨论每一位取值,值<n[i]就后面的位没有限制,如果=n[i],就发现前i位固定下来了,所以我们维护的指针也往go[u][n[i]]走一位……)
    ps.处理前导零
    因此状态需要:\(dp[i][j]\):从\(j\)点走\(i\)步可以构成串的方案数。也很好转移。
  • code:
#include<bits/stdc++.h>
using namespace std;
const int N=1e5+5;
const int mod=1e9+7;
typedef long long ll;
char s[N],a[N];
int n;
struct AC {
	int go[N][11],nd,cnt[N],fail[N];
	ll dp[1999][2005];
	void Insert() {
		int sz=strlen(s),u=0;
		for(int i=0;i<sz;i++) {
			int x=s[i]-'0';
			if(!go[u][x]) go[u][x]=++nd;
			u=go[u][x];
		}
		cnt[u]++;
	}
	int Q[N],hd,tl;
	AC() {nd=tl=0;hd=1;}
	void gt_fail() {
		for(int i=0;i<=9;i++) if(go[0][i])Q[++tl]=go[0][i];
		while(hd<=tl) {
			int u=Q[hd++];cnt[u]+=cnt[fail[u]];
			for(int i=0;i<=9;i++) {
				if(go[u][i])fail[go[u][i]]=go[fail[u]][i],Q[++tl]=go[u][i];
				else go[u][i]=go[fail[u]][i];
//				printf("%d %d: %d\n",u,i,go[u][i]);
			}
		}
	}
	void DP() {
		for(int j=0;j<=nd;j++) dp[0][j]=(!cnt[j]);
		for(int i=1;i<n;i++) {
			for(int j=0;j<=nd;j++) {
				if(cnt[j]) {continue;}
				for(int x=0;x<10;x++) {
					int y=go[j][x];
					dp[i][j]=(dp[i][j]+dp[i-1][y])%mod;
				}
			}
		}
	}
	void solve() {
		DP();
		ll ans=0;int u=0;
		for(int x=1;x<10;x++) {
			int y=go[0][x];
			for(int i=0;i<n-1;i++) ans=(ans+dp[i][y])%mod;
		}
		for(int i=1;i<=n;i++) {
			int x=a[i]-'0';
			for(int c=(i==1);c<x;c++) {
				int j=go[u][c];
				ans=(ans+dp[n-i][j])%mod;
			}
			u=go[u][x];
			if(cnt[u])break;
		}
		printf("%lld",(ans+!cnt[u])%mod);
	}
}A;

int main() {
	scanf("%s",a+1);n=strlen(a+1);
	int m;scanf("%d",&m);
	for(int i=1;i<=m;i++)scanf("%s",s),A.Insert();
	A.gt_fail();
	A.solve();
	return 0;
}