int n, d, tot; int a[kMaxN], trie[kMaxT][10], fail[kMaxT], f[kMaxD][kMaxT][2]; bool tag[kMaxT], vis[kMaxD][kMaxT][2]; std::string s, L, R;
inlineintadd(int x, int y){ return (x + y >= kMod ? x + y - kMod : x + y); } inlineintsub(int x, int y){ return (x >= y ? x - y : x - y + kMod); } inlinevoidinc(int &x, int y){ (x += y) >= kMod ? x -= kMod : x; } inlinevoiddec(int &x, int y){ (x -= y) < 0 ? x += kMod : x; }
std::string sub(std::string s){ for (int i = d; i; --i) { if (s[i] != '0') { --s[i]; for (int j = i + 1; j <= d; ++j) s[j] = '9'; break; } } return s; }
voidins(std::string s){ int cur = 0; for (auto c : s) { int k = c - '0'; if (!trie[cur][k]) trie[cur][k] = ++tot; cur = trie[cur][k]; } tag[cur] = 1; }
voidbuild(){ std::queue<int> q; for (int i = 0; i < 10; ++i) { if (trie[0][i]) { q.emplace(trie[0][i]); } } for (; !q.empty();) { int u = q.front(); q.pop(); for (int i = 0; i < 10; ++i) { if (trie[u][i]) { fail[trie[u][i]] = trie[fail[u]][i]; q.emplace(trie[u][i]); } else { trie[u][i] = trie[fail[u]][i]; } } } }
intdfs(int x, int k, bool op){ if (x > d || tag[k]) return !tag[k]; elseif (vis[x][k][op]) return f[x][k][op]; int ret = 0; for (int i = 0; i <= (op ? a[x] : 9); ++i) { inc(ret, dfs(x + 1, trie[k][i], op && (i == a[x]))); } vis[x][k][op] = 1; return f[x][k][op] = ret; }
intsolve(std::string t){ for (int i = 1; i <= d; ++i) a[i] = t[i] - '0'; int ans = 0; for (int i = 1; i <= d; ++i) ans = (10ll * ans + a[i]) % kMod; memset(f, 0, sizeof(f)), memset(vis, 0, sizeof(vis)); returnsub(ans, dfs(1, 0, 1)); }
voiddickdreamer(){ std::cin >> s >> L >> R; n = s.size(), d = L.size(); s = " " + s, L = " " + L, R = " " + R; for (int i = 1; i <= n - (d / 2) + 1; ++i) ins(s.substr(i, d / 2)); build(); std::cout << sub(solve(R), solve(sub(L))) << '\n'; }