// implement 23min #include #include #include #include #include #include #include #include #include #include #include using namespace std; typedef long long ll; typedef unsigned int uint; typedef unsigned long long ull; static const double EPS = 1e-9; static const double PI = acos(-1.0); #define REP(i, n) for (int i = 0; i < (int)(n); i++) #define FOR(i, s, n) for (int i = (s); i < (int)(n); i++) #define FOREQ(i, s, n) for (int i = (s); i <= (int)(n); i++) #define FORIT(it, c) for (__typeof((c).begin())it = (c).begin(); it != (c).end(); it++) #define MEMSET(v, h) memset((v), h, sizeof(v)) struct AhoCorasick { static const int SIZE = 128; struct State { int index; int next[SIZE]; // next[0] is failuer link vector accept; State(int index) : index(index) { memset(next, -1, sizeof(next)); } }; bool build; vector pma; vector lens; //vector strs; AhoCorasick() { build = false; pma.clear(); pma.push_back(State(0)); lens.clear(); //strs.clear(); } void AddString(const char *str) { assert(!build); int t = 0; for (int i = 0; str[i]; i++) { int c = str[i]; if (pma[t].next[c] == -1) { int m = pma.size(); pma[t].next[c] = m; pma.push_back(State(m)); } t = pma[t].next[c]; } pma[t].accept.push_back(lens.size()); lens.push_back(strlen(str)); //strs.push_back(str); } void BuildPMA() { assert(!build); queue que; // make failure link using bfs for (int c = 1; c < SIZE; c++) { if (pma[0].next[c] != -1) { pma[pma[0].next[c]].next[0] = 0; que.push(pma[0].next[c]); } else { pma[0].next[c] = 0; } } while (!que.empty()) { int t = que.front(); que.pop(); for (int c = 1; c < SIZE; c++) { if (pma[t].next[c] != -1) { que.push(pma[t].next[c]); int r = pma[t].next[0]; while (pma[r].next[c] == -1) { r = pma[r].next[0]; } pma[pma[t].next[c]].next[0] = pma[r].next[c]; for (vector::iterator it = pma[pma[r].next[c]].accept.begin(); it != pma[pma[r].next[c]].accept.end(); it++) { pma[pma[t].next[c]].accept.push_back(*it); } } } } build = true; } int OneMove(int index, int c) { return pma[index].next[c] != -1 ? pma[index].next[c] : pma[index].next[c] = OneMove(pma[index].next[0], c); //while (pma[index].next[c] == -1) { index = pma[index].next[0]; } //return pma[index].next[c]; } // return first match indices vector Match(const char *t) { assert(build); int index = 0; vector ret(lens.size(), -1); int n = strlen(t); for (int i = 0; i < n; i++) { int c = t[i]; index = OneMove(index, c); for (vector::const_iterator it = pma[index].accept.begin(); it != pma[index].accept.end(); it++) { if (ret[*it] != -1) { continue; } ret[*it] = i - lens[*it] + 1; } } return ret; } }; const ll MOD = 1e+9 + 7; int n; char A[100010]; char B[100010]; char C[100010]; AhoCorasick aho; ll dp1[2][2][2][2][510]; ll dp2[2][2][2][2][510]; int main() { while (scanf("%s %s %s", A, B, C) > 0) { n = strlen(B); int m = strlen(A); MEMSET(dp1, 0); MEMSET(dp2, 0); aho = AhoCorasick(); aho.AddString(C); aho.BuildPMA(); ll ans = 0; if (A[0] == '0' && C[0] == '0') { ans++; } memmove(A + n - m, A, sizeof(char) * m); memset(A, '0', sizeof(char) * (n - m)); dp1[0][1][1][1][0] = 1; REP(i, n) { int prev = i & 1; int next = prev ^ 1; MEMSET(dp1[next], 0); MEMSET(dp2[next], 0); REP(leadingZero, 2) { REP(lower, 2) { REP(upper, 2) { REP(index, aho.pma.size()) { if (dp1[prev][leadingZero][lower][upper][index] == 0) { continue; } int l = 0; int r = 9; if (lower) { l = A[i] - '0'; } if (upper) { r = B[i] - '0'; } FOREQ(c, l, r) { int nlower = lower && c == l; int nupper = upper && c == r; if (leadingZero && c == 0) { dp1[next][leadingZero][nlower][nupper][index] = (dp1[next][leadingZero][nlower][nupper][index] + dp1[prev][leadingZero][lower][upper][index]) % MOD; dp2[next][leadingZero][nlower][nupper][index] = (dp2[next][leadingZero][nlower][nupper][index] + dp2[prev][leadingZero][lower][upper][index]) % MOD; } else { int nindex = aho.OneMove(index, c + '0'); dp1[next][0][nlower][nupper][nindex] = (dp1[next][0][nlower][nupper][nindex] + dp1[prev][leadingZero][lower][upper][index]) % MOD; dp2[next][0][nlower][nupper][nindex] = (dp2[next][0][nlower][nupper][nindex] + dp2[prev][leadingZero][lower][upper][index]) % MOD; if (nindex == (int)aho.pma.size() - 1) { //cout << nindex << " " << index << endl; //cout << dp2[next][0][nlower][nupper][nindex] << endl; //cout << dp1[prev][leadingZero][lower][upper][index] << endl; dp2[next][0][nlower][nupper][nindex] = (dp2[next][0][nlower][nupper][nindex] + dp1[prev][leadingZero][lower][upper][index]) % MOD; } } } } } } } } REP(lower, 2) { REP(upper, 2) { REP(index, aho.pma.size()) { ans = (ans + dp2[n & 1][0][lower][upper][index]) % MOD; } } } printf("%lld\n", ans); } }