Advertisement
Dang_Quan_10_Tin

THẦN SỐ HỌC CHUYÊN SÂU

Apr 20th, 2024
855
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 2.88 KB | None | 0 0
  1. #define task "NROLOGY"
  2. #include <bits/stdc++.h>
  3.  
  4. using namespace std;
  5. using ll = long long;
  6.  
  7. constexpr int N = 5e2 + 5;
  8. constexpr ll mod = 1e9 + 7;
  9. string b, s;
  10.  
  11. ll dp[N][N][2][3], cnt[N][N][2][3];
  12. ll Pow[N];
  13.  
  14. ll d[N][N], c[N][N];
  15.  
  16. int n, m;
  17.  
  18. void Read()
  19. {
  20.     cin >> s >> b;
  21.  
  22.     reverse(b.begin(), b.end());
  23.  
  24.     while (b.size() < s.size())
  25.         b.push_back('0');
  26.     reverse(b.begin(), b.end());
  27.  
  28.     n = b.size();
  29.     m = s.size();
  30.     b = " " + b + " ";
  31.     s = " " + s + " ";
  32. }
  33.  
  34. ll toll(const string s)
  35. {
  36.     ll ans(0);
  37.  
  38.     for (auto i : s)
  39.         ans = ans * 10 + i - '0';
  40.  
  41.     return ans;
  42. }
  43.  
  44. #define bit(i, x) (((x) >> (i)) & 1)
  45.  
  46. ll f(int l, int r, bool okl, int okr)
  47. {
  48.  
  49.     ll &ans = dp[l][r][okl][okr], &res = cnt[l][r][okl][okr];
  50.  
  51.     if (ans != -1)
  52.         return ans;
  53.  
  54.     int pos = n - (l + (n + 1 - r));
  55.  
  56.     if (pos == 0)
  57.     {
  58.         res = (okl || okr != 2);
  59.         return ans = 0;
  60.     }
  61.  
  62.     ans = 0;
  63.     res = 0;
  64.  
  65.     if (okl || s[pos] <= b[l + 1])
  66.     {
  67.         (ans += f(l + 1, r, okl || s[pos] < b[l + 1], okr)) %= mod;
  68.         (ans += (s[pos] - '0') * Pow[n - (l + 1)] % mod * cnt[l + 1][r][okl || s[pos] < b[l + 1]][okr] % mod) %= mod;
  69.         (res += cnt[l + 1][r][okl || s[pos] < b[l + 1]][okr]) %= mod;
  70.     }
  71.  
  72.     {
  73.         int t;
  74.  
  75.         if (s[pos] > b[r - 1])
  76.             t = 2;
  77.         else if (s[pos] < b[r - 1])
  78.             t = 1;
  79.         else
  80.             t = okr;
  81.  
  82.         (ans += f(l, r - 1, okl, t)) %= mod;
  83.         (ans += (s[pos] - '0') * Pow[n - (r - 1)] % mod * cnt[l][r - 1][okl][t] % mod) %= mod;
  84.         (res += cnt[l][r - 1][okl][t]) %= mod;
  85.     }
  86.  
  87.     return ans;
  88. }
  89.  
  90. ll g(int l, int r)
  91. {
  92.     ll &ans = d[l][r],
  93.        &res = c[l][r];
  94.  
  95.     if (ans != -1)
  96.         return ans;
  97.  
  98.     ans = 0;
  99.     res = 0;
  100.  
  101.     int pos = m - (l + (m + 1 - r));
  102.  
  103.     if (l + 1 == r)
  104.     {
  105.         res = 1;
  106.         return 0;
  107.     }
  108.  
  109.     {
  110.         (ans += g(l + 1, r)) %= mod;
  111.         (ans += (s[pos] - '0') * Pow[m - (l + 1)] % mod * c[l + 1][r] % mod) %= mod;
  112.         (res += c[l + 1][r]) %= mod;
  113.     };
  114.     {
  115.         (ans += g(l, r - 1)) %= mod;
  116.         (ans += (s[pos] - '0') * Pow[m - (r - 1)] % mod * c[l + 1][r] % mod) %= mod;
  117.         (res += c[l][r - 1]) %= mod;
  118.     }
  119.  
  120.     return ans;
  121. }
  122.  
  123. void Solve()
  124. {
  125.     Pow[0] = 1;
  126.  
  127.     for (int i = 1; i <= n; ++i)
  128.         Pow[i] = Pow[i - 1] * 10 % mod;
  129.  
  130.     if (s.size() < b.size())
  131.     {
  132.         memset(d, -1, sizeof d);
  133.         cout << g(0, m + 1) * 500000004 % mod;
  134.     }
  135.     else
  136.     {
  137.         memset(dp, -1, sizeof dp);
  138.         cout << f(0, n + 1, 0, 0) * 500000004 % mod;
  139.     }
  140. }
  141.  
  142. int32_t main()
  143. {
  144.     ios::sync_with_stdio(0);
  145.     cin.tie(0);
  146.     cout.tie(0);
  147.     if (fopen(task ".INP", "r"))
  148.     {
  149.         freopen(task ".INP", "r", stdin);
  150.         freopen(task ".OUT", "w", stdout);
  151.     }
  152.     Read();
  153.     Solve();
  154. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement