Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <bits/stdc++.h>
- #include <ext/pb_ds/assoc_container.hpp>
- #include <ext/pb_ds/tree_policy.hpp>
- #define rep(i, a, b) for(int i = a; i < (b); ++i)
- #define all(x) begin(x), end(x)
- #define sz(x) (int)(x).size()
- typedef long long ll;
- using namespace std;
- using namespace __gnu_pbds;
- #define ld long double
- #define int long long
- #define F first
- #define S second
- #define Lnode 2*node+1
- #define Rnode 2*node+2
- #define MID (l+r>>1)
- #define el '\n'
- #define coutf(x) for(auto v:(x)) cout<<v<<' '; cout<<el
- #define coutp(x) for(auto v:(x)) cout<<v.F<<' '<<v.S<<el
- #define cinl(x) for(auto &v:(x)) cin>>v;
- #define all(x) x.begin(),x.end()
- #define ll long long
- #define sz(x) (int)x.size()
- #define pi pair<ll,ll>
- #define pii pair<ll,pair<ll,ll>>
- #define vi vector<ll>
- #define ordered_set tree<ll, null_type,less<ll>, rb_tree_tag,tree_order_statistics_node_update>
- const int N=5005,mod=1e9+7;
- using ull = unsigned long long;
- // order_of_key (k) : Number of items strictly smaller than k .
- // find_by_order(k) : K-th element in a set (counting from zero).
- struct aho_corasick {
- struct trie_node {
- vector<int> pIdxs; //probably take memory limit
- map<char, int> next;
- int fail;
- trie_node() : fail(0) {}
- bool have_next(char ch) {
- return next.find(ch) != next.end();
- }
- int& operator[](char ch) {
- return next[ch];
- }
- };
- vector<trie_node> t;
- vector<string> patterns;
- vector<int> end_of_pattern;
- vector<bool>found;
- vector<vector<int>> adj;
- int insert(const string &s, int patternIdx) {
- int root = 0;
- for (const char &ch : s) {
- if (!t[root].have_next(ch)) {
- t.push_back(trie_node());
- t[root][ch] = t.size() - 1;
- }
- root = t[root][ch];
- }
- t[root].pIdxs.push_back(patternIdx);
- return root;
- }
- int next_state(int cur, char ch) {
- while (cur > 0 && !t[cur].have_next(ch))
- cur = t[cur].fail;
- if (t[cur].have_next(ch))
- return t[cur][ch];
- return 0;
- }
- void buildAhoTree() {
- queue<int> q;
- for (auto &child : t[0].next)
- q.push(child.second);
- while (!q.empty()) {
- int cur = q.front();
- q.pop();
- for (auto &child : t[cur].next) {
- int k = next_state(t[cur].fail, child.first);
- t[child.second].fail = k;
- vector<int> &idxs = t[child.second].pIdxs;
- //dp[child.second] = max(dp[child.second],dp[k]);
- idxs.insert(idxs.end(), all(t[k].pIdxs));
- q.push(child.second);
- }
- }
- }
- void buildFailureTree() {
- adj = vector<vector<int>>(t.size());
- for (int i = 1; i < t.size(); i++)
- adj[t[i].fail].push_back(i);
- }
- aho_corasick(const vector<string> &_patterns) {
- t.push_back(trie_node());
- patterns = _patterns;
- end_of_pattern = vector<int>(patterns.size());
- found=vector<bool>(patterns.size(),false);
- for (int i = 0; i < patterns.size(); i++)
- end_of_pattern[i] = insert(patterns[i], i);
- buildAhoTree();
- //buildFailureTree();
- }
- vector<bool> match(const string &str) {
- int k = 0;
- int sum=0;
- vector<vector<int>> rt(patterns.size());
- for (int i = 0; i < str.size(); i++) {
- k = next_state(k, str[i]);
- for (auto &it : t[k].pIdxs)
- found[it]=1;
- }
- return found;
- }
- };
- ll n,k;
- ll dp[55][1005][2][2];
- string s1,s2;
- string s;
- vector<ll>num;
- ll digit(ll i,ll node,bool found,bool f,aho_corasick &ac)
- {
- if (i==n)return (found>0);
- ll &ret=dp[i][node][found][f];
- if (~ret)return ret;
- ll res=0;
- int LMT;
- if (f==0)LMT=num[i];
- else LMT=9;
- for (int dgt=0;dgt<=LMT;dgt++)
- {
- int nf=f;
- if (f==0&&dgt<LMT)nf=1;
- char ch=char('0'+dgt);
- int nnode=ac.next_state(node,ch);
- bool nfound =found;
- if (!ac.t[nnode].pIdxs.empty())nfound=1;
- res+=digit(i+1,nnode,nfound,nf,ac);
- if (res>=mod)res-=mod;
- }
- return ret=res;
- }
- ll fun(string s,aho_corasick &ac){
- num.clear();
- for (auto it:s)
- {
- num.push_back(it-'0');
- }
- n=s.size();
- memset(dp,-1,sizeof dp);
- ll ans=digit(0,0,0,0,ac);
- return ans;
- }
- string minus1(string s)
- {
- int n=s.size();
- int i=n-1;
- while (i>=0&&s[i]=='0')s[i]='9',i--;
- if (i>=0)s[i]--;
- else
- {
- for (int j=0;j<n;j++)s[j]='9';
- }
- return s;
- }
- void solve()
- {
- cin>>s;
- cin>>s1>>s2;
- vector<string>pat;
- k=(int)(s2.size()+1)/2;
- for (int i=0;i+k<=(int)s.size();i++){
- pat.push_back(s.substr(i,k));
- }
- aho_corasick ac(pat);
- bool zero=1;
- for (int i=0;i<s1.size();i++)
- {
- if (s1[i]!='0')
- {
- zero=0;
- break;
- }
- }
- ll a,b;
- if (zero==0)
- {
- s1=minus1(s1);
- b=fun(s1,ac);
- }
- else b=0;
- a=fun(s2,ac);
- ll ans=(a-b)%mod;
- if (ans<0)ans+=mod;
- cout<<ans<<"\n";
- }
- int32_t main() {
- #ifndef ONLINE_JUDGE
- freopen("in.txt", "r", stdin);
- freopen("out.txt", "w", stdout);
- #endif
- ios_base::sync_with_stdio(false);
- cin.tie(NULL);
- int tc=1;
- //cin>>tc;
- for (int i=1;i<=tc;i++){solve();}
- return 0;
- }
- /*
- */
Advertisement
Add Comment
Please, Sign In to add comment