Problem:
D: Many Decimal Integers
問題
数字 (
0
から
9
) のみからなる文字列
S
と、数字 と
?
のみからなる文字列
T
が与えられます。
S
と
T
は同じ長さです。
T
内に存在するそれぞれの
?
について、
0
から
9
までの数字のいずれか
1
つに変更し、数字のみからなる文字列
T'
を作ることを考えます。このとき、
f(T') \leq f(S)
である必要があります。ここで
f(t)
は、文字列
t
を
10
進数として読んだときの整数値を返す関数とします。
また、
T'
の最上位の桁にある数字は
0
であってもよいものとします。
あり得る文字列
T'
すべてについて、
f(T')
の値の総和を
10^9+7
で割った余りを求めてください。なお、条件を満たす
T'
がひとつも存在しない場合は
0
と答えてください。
入力形式
S
T
制約
1 \leq |S| = |T| \leq 2 \times 10^5
S
は数字 (
0
から
9
) のみからなる文字列
T
は数字と
?
のみからなる文字列
出力形式
条件を満たす
T'
の総和を
10^9+7
で割った余りを一行に出力してください。
入力例1
73
6?
出力例1
645
T'
としてあり得る文字列は、
60
から
69
までの
10
通りあります。これらの合計は
645
です。
入力例2
42
?1
出力例2
105
T'
の最上位の桁にある数字は
0
でもよいため、
01
も条件を満たします。
入力例3
1730597319
16??35??8?
出力例3
502295105
10^9 + 7
で割った余りを求めてください。

Submitted solutions:

code_snippet: #include <iostream>
#include <vector>
#include <string>
#include <algorithm>
#include <random>
#include <cassert>
#include <bitset>
#include <numeric>
#include <queue>
#include <unordered_map>
#include <climits>
#include <array>
#include <memory>
#include <iomanip>



constexpr int MOD = 1'000'000'007;

long long int powMod(long long int base, long long int exp) {
	long long int result{ 1 };
	base %= MOD;
	while (exp > 0) {
		if (exp & 1) {
			result = result * base % MOD;
		}
		base = base * base % MOD;
		exp >>= 1;
	}
	return result;
}
long long int solve(const std::string s, const std::string t) {
	const int n = s.size();
	std::vector<long long int> counts(n + 1, 1), sums(n + 1, 0);
	for (long long int digit{ 1 }, i = 1; i <= n; ++i, digit = digit * 10 % MOD) {
		switch (t[n - i]) {
		case '?':
		{
			counts[n - i] = counts[n - i + 1] * 10 % MOD;
			sums[n - i] = (sums[n - i + 1] * 10 + 45 * digit % MOD * counts[n - i + 1]) % MOD;
			break;
		}
		default:
		{
			counts[n - i] = counts[n - i + 1];
			sums[n - i] = (sums[n - i + 1] + (t[n - i] - '0') * digit % MOD * counts[n - i + 1]) % MOD;
			break;
		}
		}
	}
	long long int result{ 0 };
	long long int just{ 0 };
	int justCount{ 1 };
	for (auto i = 0; i < n; ++i) {
		const auto digit{ powMod(10, n - i - 1) };
		if (t[i] == '?')
		{
			for (auto d = 0; d < s[i] - '0'; ++d) {
				result = (result + (d * digit + just) % MOD * counts[i + 1] + sums[i + 1]) % MOD;
			}
		}
		else if (s[i] > t[i]) {
			result = ((result + ((t[i] - '0') * digit + just) % MOD * counts[i + 1])+ sums[i + 1]) % MOD;
		}
		if (t[i] != '?' && s[i] != t[i]) {
			justCount = 0;
			break;
		}
		just = (just + (s[i] - '0') * digit) % MOD;
	}
	return (result + just * justCount) % MOD;
}

int main() {
	std::string s, t;
	std::cin >> s >> t;
	const auto result{ solve(s, t) };
	std::cout << result << '\n';
}
accuracy: 1
time_ms: 10
memory_kb: 7040
final_rank: 1

code_snippet: #include <bits/stdc++.h>


#include <cassert>
#include <numeric>
#include <type_traits>

#ifdef _MSC_VER
#include <intrin.h>
#endif


#include <utility>

#ifdef _MSC_VER
#include <intrin.h>
#endif

namespace atcoder {

namespace internal {

constexpr long long safe_mod(long long x, long long m) {
    x %= m;
    if (x < 0) x += m;
    return x;
}

struct barrett {
    unsigned int _m;
    unsigned long long im;

    explicit barrett(unsigned int m) : _m(m), im((unsigned long long)(-1) / m + 1) {}

    unsigned int umod() const { return _m; }

    unsigned int mul(unsigned int a, unsigned int b) const {

        unsigned long long z = a;
        z *= b;
#ifdef _MSC_VER
        unsigned long long x;
        _umul128(z, im, &x);
#else
        unsigned long long x =
            (unsigned long long)(((unsigned __int128)(z)*im) >> 64);
#endif
        unsigned long long y = x * _m;
        return (unsigned int)(z - y + (z < y ? _m : 0));
    }
};

constexpr long long pow_mod_constexpr(long long x, long long n, int m) {
    if (m == 1) return 0;
    unsigned int _m = (unsigned int)(m);
    unsigned long long r = 1;
    unsigned long long y = safe_mod(x, m);
    while (n) {
        if (n & 1) r = (r * y) % _m;
        y = (y * y) % _m;
        n >>= 1;
    }
    return r;
}

constexpr bool is_prime_constexpr(int n) {
    if (n <= 1) return false;
    if (n == 2 || n == 7 || n == 61) return true;
    if (n % 2 == 0) return false;
    long long d = n - 1;
    while (d % 2 == 0) d /= 2;
    constexpr long long bases[3] = {2, 7, 61};
    for (long long a : bases) {
        long long t = d;
        long long y = pow_mod_constexpr(a, t, n);
        while (t != n - 1 && y != 1 && y != n - 1) {
            y = y * y % n;
            t <<= 1;
        }
        if (y != n - 1 && t % 2 == 0) {
            return false;
        }
    }
    return true;
}
template <int n> constexpr bool is_prime = is_prime_constexpr(n);

constexpr std::pair<long long, long long> inv_gcd(long long a, long long b) {
    a = safe_mod(a, b);
    if (a == 0) return {b, 0};

    long long s = b, t = a;
    long long m0 = 0, m1 = 1;

    while (t) {
        long long u = s / t;
        s -= t * u;
        m0 -= m1 * u;  // |m1 * u| <= |m1| * s <= b


        auto tmp = s;
        s = t;
        t = tmp;
        tmp = m0;
        m0 = m1;
        m1 = tmp;
    }
    if (m0 < 0) m0 += b / s;
    return {s, m0};
}

constexpr int primitive_root_constexpr(int m) {
    if (m == 2) return 1;
    if (m == 167772161) return 3;
    if (m == 469762049) return 3;
    if (m == 754974721) return 11;
    if (m == 998244353) return 3;
    int divs[20] = {};
    divs[0] = 2;
    int cnt = 1;
    int x = (m - 1) / 2;
    while (x % 2 == 0) x /= 2;
    for (int i = 3; (long long)(i)*i <= x; i += 2) {
        if (x % i == 0) {
            divs[cnt++] = i;
            while (x % i == 0) {
                x /= i;
            }
        }
    }
    if (x > 1) {
        divs[cnt++] = x;
    }
    for (int g = 2;; g++) {
        bool ok = true;
        for (int i = 0; i < cnt; i++) {
            if (pow_mod_constexpr(g, (m - 1) / divs[i], m) == 1) {
                ok = false;
                break;
            }
        }
        if (ok) return g;
    }
}
template <int m> constexpr int primitive_root = primitive_root_constexpr(m);

unsigned long long floor_sum_unsigned(unsigned long long n,
                                      unsigned long long m,
                                      unsigned long long a,
                                      unsigned long long b) {
    unsigned long long ans = 0;
    while (true) {
        if (a >= m) {
            ans += n * (n - 1) / 2 * (a / m);
            a %= m;
        }
        if (b >= m) {
            ans += n * (b / m);
            b %= m;
        }

        unsigned long long y_max = a * n + b;
        if (y_max < m) break;
        n = (unsigned long long)(y_max / m);
        b = (unsigned long long)(y_max % m);
        std::swap(m, a);
    }
    return ans;
}

}  // namespace internal

}  // namespace atcoder


#include <cassert>
#include <numeric>
#include <type_traits>

namespace atcoder {

namespace internal {

#ifndef _MSC_VER
template <class T>
using is_signed_int128 =
    typename std::conditional<std::is_same<T, __int128_t>::value ||
                                  std::is_same<T, __int128>::value,
                              std::true_type,
                              std::false_type>::type;

template <class T>
using is_unsigned_int128 =
    typename std::conditional<std::is_same<T, __uint128_t>::value ||
                                  std::is_same<T, unsigned __int128>::value,
                              std::true_type,
                              std::false_type>::type;

template <class T>
using make_unsigned_int128 =
    typename std::conditional<std::is_same<T, __int128_t>::value,
                              __uint128_t,
                              unsigned __int128>;

template <class T>
using is_integral = typename std::conditional<std::is_integral<T>::value ||
                                                  is_signed_int128<T>::value ||
                                                  is_unsigned_int128<T>::value,
                                              std::true_type,
                                              std::false_type>::type;

template <class T>
using is_signed_int = typename std::conditional<(is_integral<T>::value &&
                                                 std::is_signed<T>::value) ||
                                                    is_signed_int128<T>::value,
                                                std::true_type,
                                                std::false_type>::type;

template <class T>
using is_unsigned_int =
    typename std::conditional<(is_integral<T>::value &&
                               std::is_unsigned<T>::value) ||
                                  is_unsigned_int128<T>::value,
                              std::true_type,
                              std::false_type>::type;

template <class T>
using to_unsigned = typename std::conditional<
    is_signed_int128<T>::value,
    make_unsigned_int128<T>,
    typename std::conditional<std::is_signed<T>::value,
                              std::make_unsigned<T>,
                              std::common_type<T>>::type>::type;

#else

template <class T> using is_integral = typename std::is_integral<T>;

template <class T>
using is_signed_int =
    typename std::conditional<is_integral<T>::value && std::is_signed<T>::value,
                              std::true_type,
                              std::false_type>::type;

template <class T>
using is_unsigned_int =
    typename std::conditional<is_integral<T>::value &&
                                  std::is_unsigned<T>::value,
                              std::true_type,
                              std::false_type>::type;

template <class T>
using to_unsigned = typename std::conditional<is_signed_int<T>::value,
                                              std::make_unsigned<T>,
                                              std::common_type<T>>::type;

#endif

template <class T>
using is_signed_int_t = std::enable_if_t<is_signed_int<T>::value>;

template <class T>
using is_unsigned_int_t = std::enable_if_t<is_unsigned_int<T>::value>;

template <class T> using to_unsigned_t = typename to_unsigned<T>::type;

}  // namespace internal

}  // namespace atcoder


namespace atcoder {

namespace internal {

struct modint_base {};
struct static_modint_base : modint_base {};

template <class T> using is_modint = std::is_base_of<modint_base, T>;
template <class T> using is_modint_t = std::enable_if_t<is_modint<T>::value>;

}  // namespace internal

template <int m, std::enable_if_t<(1 <= m)>* = nullptr>
struct static_modint : internal::static_modint_base {
    using mint = static_modint;

  public:
    static constexpr int mod() { return m; }
    static mint raw(int v) {
        mint x;
        x._v = v;
        return x;
    }

    static_modint() : _v(0) {}
    template <class T, internal::is_signed_int_t<T>* = nullptr>
    static_modint(T v) {
        long long x = (long long)(v % (long long)(umod()));
        if (x < 0) x += umod();
        _v = (unsigned int)(x);
    }
    template <class T, internal::is_unsigned_int_t<T>* = nullptr>
    static_modint(T v) {
        _v = (unsigned int)(v % umod());
    }

    unsigned int val() const { return _v; }

    mint& operator++() {
        _v++;
        if (_v == umod()) _v = 0;
        return *this;
    }
    mint& operator--() {
        if (_v == 0) _v = umod();
        _v--;
        return *this;
    }
    mint operator++(int) {
        mint result = *this;
        ++*this;
        return result;
    }
    mint operator--(int) {
        mint result = *this;
        --*this;
        return result;
    }

    mint& operator+=(const mint& rhs) {
        _v += rhs._v;
        if (_v >= umod()) _v -= umod();
        return *this;
    }
    mint& operator-=(const mint& rhs) {
        _v -= rhs._v;
        if (_v >= umod()) _v += umod();
        return *this;
    }
    mint& operator*=(const mint& rhs) {
        unsigned long long z = _v;
        z *= rhs._v;
        _v = (unsigned int)(z % umod());
        return *this;
    }
    mint& operator/=(const mint& rhs) { return *this = *this * rhs.inv(); }

    mint operator+() const { return *this; }
    mint operator-() const { return mint() - *this; }

    mint pow(long long n) const {
        assert(0 <= n);
        mint x = *this, r = 1;
        while (n) {
            if (n & 1) r *= x;
            x *= x;
            n >>= 1;
        }
        return r;
    }
    mint inv() const {
        if (prime) {
            assert(_v);
            return pow(umod() - 2);
        } else {
            auto eg = internal::inv_gcd(_v, m);
            assert(eg.first == 1);
            return eg.second;
        }
    }

    friend mint operator+(const mint& lhs, const mint& rhs) {
        return mint(lhs) += rhs;
    }
    friend mint operator-(const mint& lhs, const mint& rhs) {
        return mint(lhs) -= rhs;
    }
    friend mint operator*(const mint& lhs, const mint& rhs) {
        return mint(lhs) *= rhs;
    }
    friend mint operator/(const mint& lhs, const mint& rhs) {
        return mint(lhs) /= rhs;
    }
    friend bool operator==(const mint& lhs, const mint& rhs) {
        return lhs._v == rhs._v;
    }
    friend bool operator!=(const mint& lhs, const mint& rhs) {
        return lhs._v != rhs._v;
    }

  private:
    unsigned int _v;
    static constexpr unsigned int umod() { return m; }
    static constexpr bool prime = internal::is_prime<m>;
};

template <int id> struct dynamic_modint : internal::modint_base {
    using mint = dynamic_modint;

  public:
    static int mod() { return (int)(bt.umod()); }
    static void set_mod(int m) {
        assert(1 <= m);
        bt = internal::barrett(m);
    }
    static mint raw(int v) {
        mint x;
        x._v = v;
        return x;
    }

    dynamic_modint() : _v(0) {}
    template <class T, internal::is_signed_int_t<T>* = nullptr>
    dynamic_modint(T v) {
        long long x = (long long)(v % (long long)(mod()));
        if (x < 0) x += mod();
        _v = (unsigned int)(x);
    }
    template <class T, internal::is_unsigned_int_t<T>* = nullptr>
    dynamic_modint(T v) {
        _v = (unsigned int)(v % mod());
    }

    unsigned int val() const { return _v; }

    mint& operator++() {
        _v++;
        if (_v == umod()) _v = 0;
        return *this;
    }
    mint& operator--() {
        if (_v == 0) _v = umod();
        _v--;
        return *this;
    }
    mint operator++(int) {
        mint result = *this;
        ++*this;
        return result;
    }
    mint operator--(int) {
        mint result = *this;
        --*this;
        return result;
    }

    mint& operator+=(const mint& rhs) {
        _v += rhs._v;
        if (_v >= umod()) _v -= umod();
        return *this;
    }
    mint& operator-=(const mint& rhs) {
        _v += mod() - rhs._v;
        if (_v >= umod()) _v -= umod();
        return *this;
    }
    mint& operator*=(const mint& rhs) {
        _v = bt.mul(_v, rhs._v);
        return *this;
    }
    mint& operator/=(const mint& rhs) { return *this = *this * rhs.inv(); }

    mint operator+() const { return *this; }
    mint operator-() const { return mint() - *this; }

    mint pow(long long n) const {
        assert(0 <= n);
        mint x = *this, r = 1;
        while (n) {
            if (n & 1) r *= x;
            x *= x;
            n >>= 1;
        }
        return r;
    }
    mint inv() const {
        auto eg = internal::inv_gcd(_v, mod());
        assert(eg.first == 1);
        return eg.second;
    }

    friend mint operator+(const mint& lhs, const mint& rhs) {
        return mint(lhs) += rhs;
    }
    friend mint operator-(const mint& lhs, const mint& rhs) {
        return mint(lhs) -= rhs;
    }
    friend mint operator*(const mint& lhs, const mint& rhs) {
        return mint(lhs) *= rhs;
    }
    friend mint operator/(const mint& lhs, const mint& rhs) {
        return mint(lhs) /= rhs;
    }
    friend bool operator==(const mint& lhs, const mint& rhs) {
        return lhs._v == rhs._v;
    }
    friend bool operator!=(const mint& lhs, const mint& rhs) {
        return lhs._v != rhs._v;
    }

  private:
    unsigned int _v;
    static internal::barrett bt;
    static unsigned int umod() { return bt.umod(); }
};
template <int id> internal::barrett dynamic_modint<id>::bt(998244353);

using modint998244353 = static_modint<998244353>;
using modint1000000007 = static_modint<1000000007>;
using modint = dynamic_modint<-1>;

namespace internal {

template <class T>
using is_static_modint = std::is_base_of<internal::static_modint_base, T>;

template <class T>
using is_static_modint_t = std::enable_if_t<is_static_modint<T>::value>;

template <class> struct is_dynamic_modint : public std::false_type {};
template <int id>
struct is_dynamic_modint<dynamic_modint<id>> : public std::true_type {};

template <class T>
using is_dynamic_modint_t = std::enable_if_t<is_dynamic_modint<T>::value>;

}  // namespace internal

}  // namespace atcoder


using namespace std;
using ll = long long;
using ld = long double;
using mint = atcoder::modint1000000007;
using Pair = pair<int, int>;
using Tuple = tuple<int, int, int>;
using VI1 = vector<int>;
using VI2 = vector<VI1>;
using VL1 = vector<ll>;
using VL2 = vector<VL1>;
using VD1 = vector<ld>;
using VD2 = vector<VD1>;
using VB1 = vector<bool>;
using VB2 = vector<VB1>;
using VP1 = vector<Pair>;
using VP2 = vector<VP1>;
using VT1 = vector<Tuple>;
using VT2 = vector<VT1>;
using VM1 = vector<mint>;
using VM2 = vector<VM1>;
using VM3 = vector<VM2>;
using Queue = queue<int>;
using DQ = deque<int>;
using PQ = priority_queue<int, vector<int>, greater<int>>;
using Table = VI2;
using Graph = VI2;

/** io */
template <typename T>
std::vector<T> input_vec(int N);
template <typename T>
void output_row(std::vector<T> &row);
template <typename T>
void output_col(std::vector<T> &col);
void outputYesNo(bool yes, const string &Yes = "Yes", const string &No = "No");
/** minmax */
template <typename T>
bool chmin(T &a, T b);
template <typename T>
bool chmax(T &a, T b);

void add(VM3 &dp, int i, int si, int ti) {
  dp[i + 1][0][1] += dp[i][0][1];
  dp[i + 1][1][1] += dp[i][1][1] * 10 + ti * dp[i][0][1];
  if (si > ti) {
    dp[i + 1][0][1] += dp[i][0][0];
    dp[i + 1][1][1] += dp[i][1][0] * 10 + ti * dp[i][0][0];
  } else if (si == ti) {
    dp[i + 1][0][0] += dp[i][0][0];
    dp[i + 1][1][0] += dp[i][1][0] * 10 + ti * dp[i][0][0];
  }
}

auto solve() {
  string S, T;
  cin >> S >> T;
  int N = S.size();
  VM3 dp(N + 1, VM2(2, VM1(2, 0)));
  dp[0][0][0] = 1;
  for (int i = 0; i < N; ++i) {
    int si = S.at(i) - '0';
    auto Ti = T.at(i);
    if (Ti == '?') {
      for (int ti = 0; ti < 10; ++ti) {
        add(dp, i, si, ti);
      }
    } else {
      add(dp, i, si, Ti - '0');
    }
  }
  return (dp[N][1][0] + dp[N][1][1]).val();
}

int main() {
  std::ios::sync_with_stdio(false);
  std::cin.tie(nullptr);
  int t = 1;
  // cin >> t;
  while (t--) {
    auto result = solve();
    cout << result << '\n';
    // output_row(result);
    // output_col(result);
    // outputYesNo(result, "Yes", "No");
  }
}

/** @note 使用頻度が高く毎回貼付するのが面倒なライブラリを実装しておく。*/

template <typename T>
std::vector<T> input_vec(int N) {
  std::vector<T> v(N);
  for (auto &vi : v) {
    cin >> vi;
  }
  return v;
}

void outputYesNo(bool yes, const string &Yes, const string &No) {
  if (yes)
    cout << Yes << '\n';
  else
    cout << No << '\n';
}

template <typename T>
void output_row(std::vector<T> &row) {
  int N = row.size();
  for (int i = 0; i < N; ++i) {
    if (i > 0) cout << ' ';
    cout << row.at(i);
  }
  cout << '\n';
}

template <typename T>
void output_col(std::vector<T> &col) {
  int N = col.size();
  for (int i = 0; i < N; ++i) {
    cout << col.at(i) << '\n';
  }
}

template <typename T>
bool chmin(T &a, T b) {
  if (a > b) {
    a = b;
    return true;
  }
  return false;
}

template <typename T>
bool chmax(T &a, T b) {
  if (a < b) {
    a = b;
    return true;
  }
  return false;
}
accuracy: 1
time_ms: 20
memory_kb: 33052
final_rank: 14

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ll = long long;

constexpr long long mod = 1000000007;

struct Data {
    ll n = -1;
    ll sum = -1;
    Data() = default;
    Data(ll n, ll sum) : n(n), sum(sum) {}
};

Data operator+(const Data& lhs, const Data& rhs) {
    return Data((lhs.n + rhs.n) % mod, (lhs.sum + rhs.sum) % mod);
}

bool operator==(const Data& lhs, const Data& rhs) {
    return (lhs.n == rhs.n) && (lhs.sum == rhs.sum);
}

bool operator!=(const Data& lhs, const Data& rhs) {
    return !(lhs == rhs);
}


int main() {
    string S, T;
    cin >> S >> T;

    vector<vector<Data>> memo(S.size(), vector<Data>(2));
    vector<ll> p10(S.size() + 1, 1);
    for (int i = 0; i < (int)S.size(); i++) {
        p10[i + 1] = p10[i] * 10 % mod;
    }

    vector<char> term(10);
    iota(term.begin(), term.end(), '0');
    Data init;

    auto solve = [&](auto solve, int i, bool smaller = false) -> Data {
        if (i == (int)S.size()) return Data(1, 0);
        if (memo[i][smaller] != init) return memo[i][smaller];
        
        Data res(0, 0);
        if (smaller) {
            for (char c: term) {
                if (T[i] == '?' || T[i] == c) {
                    Data now = solve(solve, i + 1, smaller);
                    res = res + now;
                    res.sum += now.n * (c - '0') % mod * p10[S.size() - i - 1] % mod;
                    res.sum %= mod;
                }
            }
        } else {
            for (char c: term) {
                if (c > S[i]) continue;
                if (T[i] != '?' && T[i] != c) continue;
                Data now;
                if (c == S[i]) {
                    now = solve(solve, i + 1);
                } else {
                    now = solve(solve, i + 1, true);
                }
                res = res + now;
                res.sum += now.n * (c - '0') % mod * p10[S.size() - i - 1] % mod;
                res.sum %= mod;
            }
        }

        return memo[i][smaller] = res;
    };

    cout << solve(solve, 0).sum << endl;
}
accuracy: 1
time_ms: 30
memory_kb: 47276
final_rank: 18

code_snippet: #include<bits/stdc++.h>
using namespace std;
using ll = long long;

const ll MOD = (ll)1e9+7;
const int MAX_N = (ll)2e5+10;

ll modpow(ll a, ll exp){
    ll res = 1, x = a;
    for(; exp > 0; exp >>= 1){
        if(exp & 1) res = res * x % MOD;
        x = x * x % MOD;
    }
    return res;
}

int main(){
    string s, t; cin >> s >> t;
    
    int N = s.size(), M = t.size();
    string tmps = "";
    for(int i = 0; i < M - N; i++) tmps += '0';
    s = tmps + s;
    string tmpt = "";
    for(int i = 0; i < N - M; i++) tmpt += '0';
    t = tmpt + t;

    N = max(N, M);
    //cerr << tmps << endl;
    //cerr << tmpt << endl;
    //cerr << s << t << endl;
    assert(s.size() == t.size() && (int)t.size() == N);


    vector<ll> p10(MAX_N), inv(11);
    p10[0] = 1;
    for(int i = 1; i < MAX_N; i++){
        p10[i] = p10[i - 1] * 10 % MOD;
    }
    for(int i = 1; i <= 10; i++) inv[i] = modpow(i, MOD - 2);

    for (int i = 1 ; i <= 10 ; i++) assert((i * inv[i]) % MOD == 1);

    vector<ll> hatena(N + 1);
    for(int i = N; i > 0; i--){
        hatena[i - 1] = hatena[i] + (t[i - 1] == '?');
    }

    vector<ll> sum(N + 1);
    for(int i = 0; i < N; i++){
        if(t[i] != '?') sum[0] = (sum[0] + ((t[i] - '0') * p10[N - i - 1])) % MOD;
    }
    for(int i = 1; i <= N; i++){
        if(t[i - 1] == '?') sum[i] = (sum[i - 1] + ll(s[i - 1] - '0') * p10[N - i]) % MOD;
        else sum[i] = sum[i - 1];
    }

    vector<ll> sum2(N + 1);
    for(int i = N - 2; i >= 0; i--){
        ll val = 0;
        if(t[i + 1] == '?'){
            val = 45 * p10[N - i - 2] % MOD;
            val = val * inv[10] % MOD;    
        }
        sum2[i] = (sum2[i + 1] + val) % MOD;
    }

    //for(int i = 0; i <= N; i++) cout << sum[i] << " " << sum2[i] << endl;


    ll ans = 0;
    bool flag = 0;
    // i [0, N)
    for(int i = 0; i < N; i++){
        if(t[i] != '?' && s[i] < t[i]){
            flag = 1;
            break;
        }
        if(s[i] == t[i] || s[i] == '0') continue;

        ll tori = (t[i] == '?') ? (s[i] - '0') : 1;
        tori = tori * p10[hatena[i + 1]] % MOD;
        //cerr << "?" << hatena[i + 1] << endl;
        ll val1 = sum[i];
        ll val2 = sum2[i];
        //cerr << tori << endl;
        ll val2_2 = 0;
        if(t[i] == '?'){
            val2_2 = (ll(s[i]-'0') * ll(s[i]-'0'-1)) / 2 * p10[N - i - 1] % MOD;
            val2_2 = val2_2 * inv[s[i] - '0'] % MOD;
        }
        //cerr << val2_2 << " v2" << endl;
        val2 = (val2 + val2_2) % MOD;

        ans = (ans + tori * val1) % MOD;
        //cout << ans << " hi" << endl;
        ans = (ans + tori * val2) % MOD;
        //cout << ans << " foo" << endl;
        //cerr << val1 << " " << val2 << " " << ans << endl;
        if(t[i] != '?' && s[i] > t[i]){
            flag = 1;
            break;
        }
        //cerr << val1 << " " << val2 << " " << ans << endl;
        //cout << ans << endl;
    }
    if(flag == 0)for(int i = 0; i < N; i++){
        ans = (ans + (s[i] - '0') * p10[N - i - 1]) % MOD;
    }
    
    cout << ans << endl;
}
accuracy: 1
time_ms: 10
memory_kb: 9640
final_rank: 3

code_snippet: #include <bits/stdc++.h>
#define rep(i,n) for(int i=0;i<(n);i++)

using namespace std;
using ll = long long;
using P = pair<int,int>;
const int mod=1000000007;
const int inf = (1<<30);

const int dy[4] = {-1,0,0,1};
const int dx[4] = {0,-1,-1,0};

template <typename T, T MOD = 1000000007>
struct Mint {
    inline static constexpr T mod = MOD;
    T v;
    Mint():v(0){}
    Mint(signed v):v(v){}
    Mint(long long t){v=t%MOD;if(v<0) v+=MOD;}

    static Mint add_identity(){return Mint(0);}
    static Mint mul_identity(){return Mint(1);}

    Mint& operator+=(Mint a){v+=a.v;if(v>=MOD)v-=MOD;return *this;}
    Mint& operator-=(Mint a){v+=MOD-a.v;if(v>=MOD)v-=MOD;return *this;}
    Mint& operator*=(Mint a){v=1LL*v*a.v%MOD;return *this;}

    Mint operator+(Mint a) const{return Mint(v)+=a;}
    Mint operator-(Mint a) const{return Mint(v)-=a;}
    Mint operator*(Mint a) const{return Mint(v)*=a;}
    Mint operator*(int a) const{return Mint(v)*=Mint(a);}

    Mint operator+() const{return *this;}
    Mint operator-() const{return v?Mint(MOD-v):Mint(v);}

    friend Mint operator*(int lhs, Mint rhs) {
        return Mint(lhs)*rhs;
    }
};

template<typename T, T MOD>
ostream& operator<<(ostream &os,Mint<T, MOD> m){os<<m.v;return os;}

using mint = Mint<int>;

int main() {
    string s,t;
    cin>>s>>t;
    int n  = s.size();
    vector<vector<mint>> dp(n+1,vector<mint>(2));
    vector<vector<mint>> A(n+1,vector<mint>(2));
    A[0][1] = 1;
    vector<mint> sum(11);
    rep(i,10){
        sum[i+1] = sum[i]+i+1;
        //cout<<sum[i+1]<<" ";
    }
    //cout<<endl;

    for(int i = 0; i<n; i++){
        if(t[i] == '?'){
            dp[i+1][1] = (dp[i][1] *10 + (int)(s[i]-'0')*A[i][1]);
            dp[i+1][0] = ((dp[i][0]*10*10) + (45*A[i][0]));
            dp[i+1][0] = (dp[i+1][0] + (dp[i][1]*10 * (max(0,(int)(s[i]-'0')))) 
                                        + (A[i][1]*(sum[max(0,((int)(s[i]-'0')-1))])));

            A[i+1][1] = A[i][1];
            A[i+1][0] = (A[i][0]*10 + A[i][1]*(max((int)(s[i]-'0'),0)));
        }else{
            if(s[i] == t[i]){
                dp[i+1][1] = (dp[i][1]*10+((int)(s[i]-'0')*A[i][1]));
                dp[i+1][0] = ((dp[i][0]*10)+(((int)(s[i]-'0')*A[i][0])));

                A[i+1][1] = A[i][1];
                A[i+1][0] = A[i][0];
            }else if(s[i] < t[i]){
                dp[i+1][1] = 0;
                dp[i+1][0] = ((dp[i][0]*10) + (((int)(t[i]-'0')*A[i][0])));

                A[i+1][1] = 0;
                A[i+1][0] = A[i][0];
            }else{
                dp[i+1][1] = 0;
                dp[i+1][0] = ((dp[i][0]*10)+(((int)(t[i] -'0') * A[i][0])));
                dp[i+1][0] = (dp[i+1][0] + ((dp[i][1]*10 + (int)(t[i]-'0')*A[i][1])));

                A[i+1][1] = 0;
                A[i+1][0] = (A[i][0] + A[i][1]);
            }
        }
       // cout<<dp[i+1][0]<<" "<<dp[i+1][1]<<" "<<A[i+1][0]<<" "<<A[i+1][1]<<endl;
    }
    cout<<(dp[n][1]+dp[n][0])<<endl;



}
accuracy: 1
time_ms: 20
memory_kb: 25376
final_rank: 13

code_snippet: #include<bits/stdc++.h>

using namespace std;

using ll = long long;
const ll MOD = 1e9 + 7;

ll func(){
  string s;
  string t;
  cin >> s >> t;
  int n = s.size();
  vector<ll> pow10(1,1);
  for(int i=0;i<n-1;++i){
    ll add = pow10.back() * 10 % MOD;
    pow10.push_back(add);
  }

  reverse(pow10.begin(),pow10.end());

  using P = pair<ll,ll>;
  vector<vector<P>> dp(2,vector<P>(n,P(-1,-1)));
  auto rec = [&](auto rec, int p,bool touch) -> P{
    if(p == n)return P(1,0);
    auto &it = dp[touch][p];
    if(it.first >= 0)return it;
    it = P(0,0);
    for(int i=0;i<10;++i){
      int c = i + '0';
      if(t[p] != '?' and t[p] != c)continue;
      if(touch and s[p] < c)break;
      int ntouch = touch and s[p] == c;
      P tmp = rec(rec, p + 1, ntouch);
      it.second += pow10[p] * i % MOD * tmp.first;
      it.second += tmp.second;
      it.second %= MOD;
      it.first += tmp.first;
      it.first %= MOD;
    }
    return it;
  };
  return rec(rec, 0, true).second;
}

int main(){
  cout << func() << endl;
}
accuracy: 1
time_ms: 20
memory_kb: 36332
final_rank: 15

code_snippet: #include<iostream>
#include<algorithm>
#include<vector>
#include<string>
#include<utility>
#include<map>
#include<set>
#include<queue>
#include<stack>
#include<functional>
#include<math.h>
#include<random>
#include <bitset>
using namespace std;
#define N (1000000000+7)
//#define N 998244353
#define INF 1e16
typedef long long ll;
typedef pair<int,int> P;
typedef pair<int,P> Q;

const int inf = (int)1e9; 

ll gcd(ll a, ll b) {
	if (b > a) {
		ll tmp = b;
		b = a;
		a = tmp;
	}
	if (a%b == 0)return b;
	else return gcd(b, a%b);
}

ll dp[200010][2][2];

ll ten[200010];

int main(void){
	string S,T;
	cin>>S>>T;
	ll n = S.length();
	dp[0][1][0]=1;
	dp[0][0][0]=0;
	ten[0]=1;
	for(ll i=0;i<=200000;i++){
		ten[i+1] = (10*ten[i])%N;
	}
	for(ll i=0;i<n;i++){
		if(T[i]=='?'){
			ll x = S[i]-'0';
			ll s = x*(x-1)/2;
			dp[i+1][1][0] = dp[i][1][0];
			dp[i+1][0][0] = ((dp[i][1][0]*x)%N+(dp[i][0][0])*10)%N;
			dp[i+1][1][1] = dp[i][1][1] + (x*((dp[i+1][1][0]*ten[n-i-1])%N))%N;
			dp[i+1][1][1] = dp[i+1][1][1]%N;
			dp[i+1][0][1] = (dp[i][0][1]*10)%N+(45*((ten[n-i-1]*dp[i][0][0])%N))%N;
			dp[i+1][0][1] = dp[i+1][0][1]%N;
			dp[i+1][0][1] = dp[i+1][0][1]+ (dp[i][1][1]*x)%N+(((s*ten[n-i-1])%N)*(dp[i][1][0]))%N;
			dp[i+1][0][1] = dp[i+1][0][1]%N;
		}
		else{
			if(S[i]==T[i]){
				ll x = T[i]-'0';
				dp[i+1][1][0] = dp[i][1][0];
				dp[i+1][0][0] = dp[i][0][0];
				dp[i+1][1][1] = dp[i][1][1] + (((x*ten[n-i-1])%N)*dp[i][1][0])%N;
				dp[i+1][0][1] = dp[i][0][1] + (((x*ten[n-i-1])%N)*dp[i][0][0])%N;
				dp[i+1][1][1] = dp[i+1][1][1]%N;
				dp[i+1][0][1] = dp[i+1][0][1]%N;
			}
			else{
				if(S[i]<T[i]){
					ll x = T[i]-'0';
					dp[i+1][0][0] = dp[i][0][0];
					dp[i+1][0][1] = dp[i][0][1]+(((x*ten[n-i-1])%N)*dp[i+1][0][0])%N;
					dp[i+1][0][1] = dp[i+1][0][1]%N;
				}
				else{
					ll x = T[i]-'0';
					dp[i+1][0][0] = (dp[i][0][0]+dp[i][1][0])%N;
					dp[i+1][0][1] = (dp[i][0][1]+dp[i][1][1])%N+(((x*ten[n-i-1])%N)*dp[i+1][0][0])%N;
					dp[i+1][0][1] = dp[i+1][0][1]%N;
				}
			}
		}
	}
	//cout<<dp[3][0][0]<<endl;
	cout<<(dp[n][0][1]+dp[n][1][1])%N<<endl;
	return 0;
}
accuracy: 1
time_ms: 10
memory_kb: 11100
final_rank: 8

code_snippet: #include <bits/stdc++.h>
using namespace std;
template<class T> inline bool chmax(T& a, T b) { if (a < b) { a = b; return true; } return false; }
template<class T> inline bool chmin(T& a, T b) { if (a > b) { a = b; return true; } return false; }
using ll = long long;
using P = pair<ll, ll>;
const long double PI = acos(-1.0L);
ll GCD(ll a, ll b) { return b?GCD(b, a%b):a; }
ll LCM(ll a, ll b) { return a/GCD(a, b)*b; }

// auto mod int
const int mod = 1000000007;
// const int mod = 998244353;
struct mint {
    ll x; // typedef long long ll;
    mint(ll x=0):x((x%mod+mod)%mod){}
    mint operator-() const { return mint(-x);}
    mint& operator+=(const mint a) {
      if ((x += a.x) >= mod) x -= mod;
      return *this;
    }
    mint& operator-=(const mint a) {
      if ((x += mod-a.x) >= mod) x -= mod;
      return *this;
    }
    mint& operator*=(const mint a) { (x *= a.x) %= mod; return *this;}
    mint operator+(const mint a) const { return mint(*this) += a;}
    mint operator-(const mint a) const { return mint(*this) -= a;}
    mint operator*(const mint a) const { return mint(*this) *= a;}
    mint pow(ll t) const {
      if (!t) return 1;
      mint a = pow(t>>1);
      a *= a;
      if (t&1) a *= *this;
      return a;
    }

    // for prime mod
    mint inv() const { return pow(mod-2);}
    mint& operator/=(const mint a) { return *this *= a.inv();}
    mint operator/(const mint a) const { return mint(*this) /= a;}
};
istream& operator>>(istream& is, mint& a) { return is >> a.x;}
ostream& operator<<(ostream& os, const mint& a) { return os << a.x;}

string s, t;
// dp[上から何桁目][未満フラグ]
mint dp[200200][2];     // 求めたい答え
mint num[200200][2];    // 組み合わせの数

int main() {
    cin >> s >> t;
    int slen = s.length();
    memset(dp, 0, sizeof(dp));
    memset(num, 0, sizeof(num));
    num[0][1] = 1;

    for(int i = 0; i < slen; ++i) {
      int sch = s[i] - '0';
      if(t[i] == '?') {
        // tが?だったとき
        // 未満の時、未満→未満
        for(int d = 0; d <= 9; ++d) {
          dp[i+1][0] += (dp[i][0]*(mint)10 + (mint)d*num[i][0]);
          num[i+1][0] += num[i][0];
        }

        // 一致しているとき、一致→一致or一致→未満
        for(int d = 0; d < sch; ++d) {
          dp[i+1][0] += (dp[i][1]*(mint)10 + (mint)d*num[i][1]);
          num[i+1][0] += num[i][1];
        }
        dp[i+1][1] += (dp[i][1]*(mint)10 + (mint)sch*num[i][1]);
        num[i+1][1] += num[i][1];
        
      }else {
        int tch = t[i] - '0';
        // 未満の時、未満→未満、tchが何であっても処理は一緒
        dp[i+1][0] += (dp[i][0]*(mint)10 + (mint)tch*num[i][0]);
        num[i+1][0] += num[i][0];

        // 一致しているとき、一致→一致or一致→未満
        if(tch == sch) {
          dp[i+1][1] += (dp[i][1]*(mint)10 + (mint)tch*num[i][1]);
          num[i+1][1] += num[i][1];
        }else if(tch < sch) {
          dp[i+1][0] += (dp[i][1]*(mint)10 + (mint)tch*num[i][1]);
          num[i+1][0] += num[i][1];
        }
      }
    }
    mint ans = dp[slen][0] + dp[slen][1];
    cout << ans << endl;
}
accuracy: 1
time_ms: 20
memory_kb: 9852
final_rank: 11

code_snippet: #include <bits/stdc++.h>
#define MOD (long long)(1e9 + 7)
using namespace std;

long long ssize = 0;
long long dp[200005][2] = {0}, sum[200005][2] = {0};
string s, t;

long long solve();

int main() {
  cin >> s >> t;
  cout << solve() << endl;
  return 0;
}

long long solve() {
  ssize = s.size();
  dp[0][0] = 1;
  for(int i = 0; i < ssize; ++i) {
    int nums = s[i] - '0', numt = t[i] - '0';
    if(t[i] != '?') {
      if(nums == numt) {
        (dp[i + 1][1] += dp[i][1]) %= MOD;
        (dp[i + 1][0] += dp[i][0]) %= MOD;

        sum[i + 1][1] +=
            (sum[i][1] * 10 % MOD + dp[i][1] * numt % MOD) %
            MOD;
        sum[i + 1][1] %= MOD;
        sum[i + 1][0] +=
            (sum[i][0] * 10 % MOD + dp[i][0] * numt % MOD) %
            MOD;
        sum[i + 1][0] %= MOD;
      }
      else if(nums < numt) {
        dp[i + 1][1] += dp[i][1];
        dp[i + 1][1] %= MOD;

        sum[i + 1][1] +=
            (sum[i][1] * 10 % MOD + dp[i][1] * numt % MOD) %
            MOD;
        sum[i + 1][1] %= MOD;
      }
      else {
        dp[i + 1][1] += dp[i][1];
        (dp[i + 1][1] += dp[i][0]) %= MOD;

        sum[i + 1][1] +=
            (sum[i][1] * 10 % MOD + dp[i][1] * numt % MOD) %
            MOD;
        sum[i + 1][1] %= MOD;
        sum[i + 1][1] +=
            (sum[i][0] * 10 % MOD + dp[i][0] * numt % MOD) %
            MOD;
        sum[i + 1][1] %= MOD;
      }
    }
    else {
      for(int k = 0; k < 10; ++k) {
        numt = k;
        if(nums == numt) {
          (dp[i + 1][1] += dp[i][1]) %= MOD;
          (dp[i + 1][0] += dp[i][0]) %= MOD;

          sum[i + 1][1] += (sum[i][1] * 10 % MOD +
                            dp[i][1] * numt % MOD) %
                           MOD;
          sum[i + 1][1] %= MOD;
          sum[i + 1][0] += (sum[i][0] * 10 % MOD +
                            dp[i][0] * numt % MOD) %
                           MOD;
          sum[i + 1][0] %= MOD;
        }
        else if(nums < numt) {
          dp[i + 1][1] += dp[i][1];
          dp[i + 1][1] %= MOD;

          sum[i + 1][1] += (sum[i][1] * 10 % MOD +
                            dp[i][1] * numt % MOD) %
                           MOD;
          sum[i + 1][1] %= MOD;
        }
        else {
          dp[i + 1][1] += dp[i][1];
          (dp[i + 1][1] += dp[i][0]) %= MOD;

          sum[i + 1][1] += (sum[i][1] * 10 % MOD +
                            dp[i][1] * numt % MOD) %
                           MOD;
          sum[i + 1][1] %= MOD;
          sum[i + 1][1] += (sum[i][0] * 10 % MOD +
                            dp[i][0] * numt % MOD) %
                           MOD;
          sum[i + 1][1] %= MOD;
        }
      }
    }
  }

  return (sum[ssize][1] + sum[ssize][0]) % MOD;
}
accuracy: 1
time_ms: 10
memory_kb: 9612
final_rank: 2

code_snippet: #include <iostream>
#include <string>
#include <cstdlib>
#include <cmath>
#include <vector>
#include <map>
#include <set>
#include <algorithm>
#include <queue>
#include <stack>
#include <functional>
#include <bitset>
#include <assert.h>
using namespace std;
typedef long long ll;
typedef vector<ll> vl;
typedef vector<vl> vvl;
typedef vector<char> vc;
typedef vector<string> vs;
typedef vector<bool> vb;
typedef vector<double> vd;
typedef pair<ll,ll> P;
typedef vector<P> vpl;
typedef tuple<ll,ll,ll> tapu;
#define rep(i,n) for(ll i=0; i<(n); i++)
#define REP(i,a,b) for(int i=(a); i<(b); i++)
#define all(x) (x).begin(), (x).end()
#define rall(x) (x).rbegin(), (x).rend()
const int inf = 1<<30;
const ll linf = 1LL<<62;
const int MAX = 510000;
ll dy[8] = {0,1,0,-1,1,-1,1,-1};
ll dx[8] = {1,0,-1,0,1,-1,-1,1};
const double pi = acos(-1);
const double eps = 1e-7;
template<typename T1,typename T2> inline bool chmin(T1 &a,T2 b){
	if(a>b){
		a = b; return true;
	}
	else return false;
}
template<typename T1,typename T2> inline bool chmax(T1 &a,T2 b){
	if(a<b){
		a = b; return true;
	}
	else return false;
}
template<typename T1,typename T2> inline void print2(T1 a, T2 b){cout << a << " " << b << "\n";}
template<typename T1,typename T2,typename T3> inline void print3(T1 a, T2 b, T3 c){
	cout << a << " " << b << " " << c << "\n";
}
const int mod = 1e9 + 7;
//const int mod = 998244353;

template <std::uint_fast64_t Modulus> class modint {
  using u64 = std::uint_fast64_t;

public:
  u64 a;

  constexpr modint(const u64 x = 0) noexcept : a(x % Modulus) {}
  constexpr u64 &value() noexcept { return a; }
  constexpr const u64 &value() const noexcept { return a; }
  constexpr modint operator+(const modint rhs) const noexcept {
	return modint(*this) += rhs;
  }
  constexpr modint operator-(const modint rhs) const noexcept {
	return modint(*this) -= rhs;
  }
  constexpr modint operator*(const modint rhs) const noexcept {
	return modint(*this) *= rhs;
  }
  constexpr modint operator/(const modint rhs) const noexcept {
	return modint(*this) /= rhs;
  }
  constexpr modint &operator+=(const modint rhs) noexcept {
	a += rhs.a;
	if (a >= Modulus) {
	  a -= Modulus;
	}
	return *this;
  }
  constexpr modint &operator-=(const modint rhs) noexcept {
	if (a < rhs.a) {
	  a += Modulus;
	}
	a -= rhs.a;
	return *this;
  }
  constexpr modint &operator*=(const modint rhs) noexcept {
	a = a * rhs.a % Modulus;
	return *this;
  }
  constexpr modint &operator/=(modint rhs) noexcept {
	u64 exp = Modulus - 2;
	while (exp) {
	  if (exp % 2) {
		*this *= rhs;
	  }
	  rhs *= rhs;
	  exp /= 2;
	}
	return *this;
  }
};

using mint = modint<mod>;

mint dp[202020][2];
mint ep[202020][2];

int main(){
	string s,t; cin >> s >> t;
	ll n = s.size();
	ep[0][0] = 1;
	rep(i,n){
		if(t[i]=='?'){
			ll num = s[i] - '0';
			rep(j,10){
				if(j < num){
					dp[i+1][1] += (dp[i][0] + dp[i][1]) * 10 + 
							(mint)j * (ep[i][0] + ep[i][1]);
					ep[i+1][1] += ep[i][1] + ep[i][0];
				}else if(j == num){
					dp[i+1][1] += dp[i][1] * 10 + (mint)j * ep[i][1];
					dp[i+1][0] += dp[i][0] * 10 + (mint)j * ep[i][0];
					ep[i+1][1] += ep[i][1];
					ep[i+1][0] += ep[i][0];
				}else{
					dp[i+1][1] += dp[i][1] * 10 + (mint)j * ep[i][1];
					ep[i+1][1] += ep[i][1];
				}
			}
		}else{
			ll num = t[i] - '0';
			if(t[i] < s[i]){
				dp[i+1][1] += (dp[i][0] + dp[i][1]) * 10 + 
							(mint)num * (ep[i][0] + ep[i][1]);
				ep[i+1][1] += ep[i][1] + ep[i][0];
			}else if(t[i] == s[i]){
				dp[i+1][1] += dp[i][1] * 10 + (mint)num * ep[i][1];
				dp[i+1][0] += dp[i][0] * 10 + (mint)num * ep[i][0];
				ep[i+1][1] += ep[i][1];
				ep[i+1][0] += ep[i][0];
			}else{
				dp[i+1][1] += dp[i][1] * 10 + (mint)num * ep[i][1];
				ep[i+1][1] += ep[i][1];
			}
		}
	}
	mint ans = dp[n][0] + dp[n][1];
	cout << ans.value() << endl;
}
accuracy: 1
time_ms: 20
memory_kb: 9628
final_rank: 10

code_snippet: #include <bits/stdc++.h>
using namespace std;
#define rep(i,n) for(int i = 0; i < (n);i++)
#define sz(x) int(x.size())
typedef long long ll;
typedef pair<int,int> P;

const ll mod = 1e9+7;

ll dp[200010][2][2];

int main(){
  string s, t;
  cin >> s >> t;

  int n = sz(s);
  dp[0][0][1] = 1;
  rep(i,n) {
    const int sD = s[i] - '0'; 
    if (t[i] == '?') {
      rep(j,2) {
        for (int d = 0; d <= (j ? 9 : sD); d++) {
          (dp[i+1][j||(d<sD)][0] += dp[i][j][0] * 10 + d * dp[i][j][1]) %= mod;
          (dp[i+1][j||(d<sD)][1] += dp[i][j][1]) %= mod;
        }
      }
    } else {
      const int tD = t[i] - '0';
      rep(j,2) {
        if (sD < tD && j == 0) continue;
        (dp[i+1][j||(tD<sD)][0] += dp[i][j][0] * 10 + tD * dp[i][j][1]) %= mod;
        (dp[i+1][j||(tD<sD)][1] += dp[i][j][1]) %= mod;
      }
    }
  }
  cout << (dp[n][0][0] + dp[n][1][0]) % mod << endl;
  return 0;
}
accuracy: 1
time_ms: 10
memory_kb: 9696
final_rank: 5

code_snippet: #include <bits/stdc++.h>
using namespace std;
#define rep(i,n) for(int i = 0; i < (n);i++)
#define sz(x) int(x.size())
typedef long long ll;
typedef pair<int,int> P;

const ll mod = 1e9+7;

ll dp[200010][2][2];

int main(){
  string s, t;
  cin >> s >> t;

  int n = sz(s);
  dp[0][0][1] = 1;
  rep(i,n) {
    const int sD = s[i] - '0'; 
    if (t[i] == '?') {
      rep(j,2) {
        for (int d = 0; d <= (j ? 9 : sD); d++) {
          (dp[i+1][j||(d<sD)][0] += dp[i][j][0] * 10 + d * dp[i][j][1]) %= mod;
          (dp[i+1][j||(d<sD)][1] += dp[i][j][1]) %= mod;
        }
      }
    } else {
      const int tD = t[i] - '0';
      rep(j,2) {
        (dp[i+1][j||(tD<sD)][0] += dp[i][j][0] * 10 + tD * dp[i][j][1]) %= mod;
        (dp[i+1][j||(tD<sD)][1] += dp[i][j][1]) %= mod;
      }
    }
  }
  cout << (dp[n][0][0] + dp[n][1][0]) % mod << endl;
  return 0;
}
accuracy: 0.08333333333333333
time_ms: 10
memory_kb: 7380
final_rank: 19

code_snippet: #include <bits/stdc++.h>
#define GET_MACRO(_1,_2,_3,_4,_5,_6,_7,_8,NAME,...) NAME
#define pr(...) cerr<< GET_MACRO(__VA_ARGS__,pr8,pr7,pr6,pr5,pr4,pr3,pr2,pr1)(__VA_ARGS__) <<endl
#define pr1(a) (#a)<<"="<<(a)<<" "
#define pr2(a,b) pr1(a)<<pr1(b)
#define pr3(a,b,c) pr1(a)<<pr2(b,c)
#define pr4(a,b,c,d) pr1(a)<<pr3(b,c,d)
#define pr5(a,b,c,d,e) pr1(a)<<pr4(b,c,d,e)
#define pr6(a,b,c,d,e,f) pr1(a)<<pr5(b,c,d,e,f)
#define pr7(a,b,c,d,e,f,g) pr1(a)<<pr6(b,c,d,e,f,g)
#define pr8(a,b,c,d,e,f,g,h) pr1(a)<<pr7(b,c,d,e,f,g,h)
#define prArr(a) {cerr<<(#a)<<"={";int i=0;for(auto t:(a))cerr<<(i++?", ":"")<<t;cerr<<"}"<<endl;}
using namespace std;
using Int = long long;
using _int = int;
using ll = long long;
using Double = long double;
const Int INF = (1LL<<60)+1e9; // ~ 1.15 * 1e18
const Int mod = (1e9)+7;
const Double EPS = 1e-8;
const Double PI = 6.0 * asin((Double)0.5);
using P = pair<Int,Int>;
template<class T> T Max(T &a,T b){return a=max(a,b);}
template<class T> T Min(T &a,T b){return a=min(a,b);}
template<class T1, class T2> ostream& operator<<(ostream& o,pair<T1,T2> p){return o<<"("<<p.first<<","<<p.second<<")";}
template<class T1, class T2, class T3> ostream& operator<<(ostream& o,tuple<T1,T2,T3> t){
  return o<<"("<<get<0>(t)<<","<<get<1>(t)<<","<<get<2>(t)<<")";}
template<class T1, class T2> istream& operator>>(istream& i,pair<T1,T2> &p){return i>>p.first>>p.second;}
template<class T> ostream& operator<<(ostream& o,vector<T> a){Int i=0;for(T t:a)o<<(i++?" ":"")<<t;return o;}
template<class T> istream& operator>>(istream& i,vector<T> &a){for(T &t:a)i>>t;return i;}
//INSERT ABOVE HERE

string S, T;
vector<Int> B;

Int dfs2(Int idx, Int same){
  static Int mem[200010][2], used[200010][2];
  if(idx == (Int)T.size()) return 1;
  if(used[idx][same]++) return mem[idx][same];

  Int res = 0;
  for(Int num=0;num<10;num++){
    if(isdigit(T[idx]) && num != T[idx] - '0') continue;
    if(same && S[idx] - '0' < num) continue;
    Int nsame = same & (S[idx] - '0' == num);
    res += dfs2(idx + 1, nsame);
    res %= mod;
  }
  return mem[idx][same] = res;
}

Int dfs(Int idx, Int same, Int keta){
  static Int mem[200010][2], used[200010][2];
  if(idx == (Int)T.size()) return 0;
  if(used[idx][same]++) return mem[idx][same];
  Int res = 0, update = 0;
  for(Int num=0;num<10;num++){
    if(isdigit(T[idx]) && num != T[idx] - '0') continue;
    if(same && S[idx] - '0' < num) continue;
    Int nsame = same && (S[idx] - '0' == num);
    Int t = dfs(idx + 1, nsame, keta-1);
    if(t == -1) continue;
    update = 1;
    res += B[keta] * num * dfs2(idx + 1, nsame) + t;
    res %= mod;
  }
  if(!update) res = -1;
  return mem[idx][same] = res;
}


signed main(){
  srand((unsigned)time(NULL));
  cin.tie(0);
  ios_base::sync_with_stdio(0);
  cout << fixed << setprecision(12);

  cin>>S;
  cin>>T;
  {
    reverse(S.begin(), S.end());
    reverse(T.begin(), T.end());
    while(S.size() < T.size()) S += '0';
    while(T.size() < S.size()) T += '0';
    reverse(S.begin(), S.end());
    reverse(T.begin(), T.end());
  }

  const Int N = 200010;
  B.resize(N);
  B[0] = 1;
  for(Int i=1;i<N;i++) B[i] = B[i-1] * 10 % mod;
  Int ans = dfs(0, 1, T.size() - 1);
  if(ans == -1) ans = 0;
  cout<<ans<<endl;


  return 0;
}
accuracy: 1
time_ms: 20
memory_kb: 36332
final_rank: 15

code_snippet: #include <iostream>
#include <vector>
#include <map>
#include <set>
#include <queue>
#include <string>
#include <iomanip>
#include <algorithm>
#include <cmath>
#include <stdio.h>
using namespace std;
#define int long long
int MOD = 1000000007;
int p10[300010];
void add(int &a, const int &b) {
	a += b;
	if (a >= MOD) {
		a -= MOD;
	}
}
signed main() {
	cin.tie(0);
	ios::sync_with_stdio(false);
	p10[0] = 1;
	for (int i = 1; i <= 300005; i++) {
		p10[i] = (p10[i - 1] * 10) % MOD;
	}
	string S;
	cin >> S;
	string T;
	cin >> T;
	int N = S.size();

	vector<vector<int> > dp(N + 1, vector<int>(2, 0));
	vector<vector<int> > sum(N + 1, vector<int>(2, 0));
	dp[0][0] = 1;
	sum[0][0] = 0;
	for (int i = 0; i < N; i++) {
		int mn, mx;
		if (T[i] == '?') {
			mx = 9;
			mn = 0;
		}
		else {
			mn = mx = T[i] - '0';
		}
		for (int j = mn; j <= mx; j++) {
			int t = (j * p10[N - 1 - i]) % MOD;
			add(dp[i + 1][1], dp[i][1]);
			add(sum[i + 1][1], (sum[i][1] + dp[i][1] * t) % MOD);
			if (S[i] - '0' == j) {
				add(dp[i + 1][0], dp[i][0]);
				add(sum[i + 1][0], (sum[i][0] + dp[i][0] * t) % MOD);
			}
			else if (S[i] - '0' > j) {
				add(dp[i + 1][1], dp[i][0]);
				add(sum[i + 1][1], (sum[i][0] + dp[i][0] * t) % MOD);
			}
		}
	}
	int res = 0;
	add(res, sum.back()[0]);
	add(res, sum.back()[1]);
	cout << res << endl;
}
accuracy: 1
time_ms: 40
memory_kb: 27600
final_rank: 17

code_snippet: #include <iostream>
#include <vector>
#include <map>
#include <set>
#include <queue>
#include <string>
#include <iomanip>
#include <algorithm>
#include <cmath>
#include <stdio.h>
using namespace std;
#define int long long
int MOD = 1000000007;
int p10[100010];
void add(int &a, const int &b) {
	a += b;
	if (a >= MOD) {
		a -= MOD;
	}
}
signed main() {
	cin.tie(0);
	ios::sync_with_stdio(false);
	p10[0] = 1;
	for (int i = 1; i <= 100005; i++) {
		p10[i] = (p10[i - 1] * 10) % MOD;
	}
	string S;
	cin >> S;
	string T;
	cin >> T;
	int N = S.size();

	vector<vector<int> > dp(N + 1, vector<int>(2, 0));
	vector<vector<int> > sum(N + 1, vector<int>(2, 0));
	dp[0][0] = 1;
	sum[0][0] = 0;
	for (int i = 0; i < N; i++) {
		int mn, mx;
		if (T[i] == '?') {
			mx = 9;
			mn = 0;
		}
		else {
			mn = mx = T[i] - '0';
		}
		for (int j = mn; j <= mx; j++) {
			int t = (j * p10[N - 1 - i]) % MOD;
			add(dp[i + 1][1], dp[i][1]);
			add(sum[i + 1][1], (sum[i][1] + dp[i][1] * t) % MOD);
			if (S[i] - '0' == j) {
				add(dp[i + 1][0], dp[i][0]);
				add(sum[i + 1][0], (sum[i][0] + dp[i][0] * t) % MOD);
			}
			else if (S[i] - '0' > j) {
				add(dp[i + 1][1], dp[i][0]);
				add(sum[i + 1][1], (sum[i][0] + dp[i][0] * t) % MOD);
			}
		}
	}
	int res = 0;
	add(res, sum.back()[0]);
	add(res, sum.back()[1]);
	cout << res << endl;
}
accuracy: 0.08333333333333333
time_ms: 10
memory_kb: 10440
final_rank: 20

code_snippet: #include <bits/stdc++.h>
using namespace std;
template <class T>
inline bool chmax(T &a, T b)
{
    if (a < b)
    {
        a = b;
        return 1;
    }
    return 0;
}
template <class T>
inline bool chmin(T &a, T b)
{
    if (a > b)
    {
        a = b;
        return 1;
    }
    return 0;
}
typedef long long int ll;

#define ALL(v) (v).begin(), (v).end()
#define RALL(v) (v).rbegin(), (v).rend()
#define endl "\n"
const double EPS = 1e-7;
const int INF = 1 << 30;
const ll LLINF = 1LL << 60;
const double PI = acos(-1);
const int MOD = 1000000007;
const int dx[4] = {1, 0, -1, 0};
const int dy[4] = {0, 1, 0, -1};

//-------------------------------------

ll dp[300000][2] = {0};
ll sum[300000][2] = {0};

int main()
{
    cin.tie(0);
    ios::sync_with_stdio(false);
    string s, t;
    cin >> s >> t;
    ll n = s.size();
    dp[0][0] = 1;
    for (ll i = 0; i < n; i++)
    {
        ll sNum = s[i] - '0';
        ll tNum = t[i] - '0';
        if (t[i] != '?')
        {
            if (sNum == tNum)
            {
                (dp[i + 1][0] += dp[i][0]) %= MOD;
                (dp[i + 1][1] += dp[i][1]) %= MOD;
                (sum[i + 1][1] += (sum[i][1] * 10 % MOD + dp[i][1] * tNum % MOD) % MOD) %= MOD;
                (sum[i + 1][0] += (sum[i][0] * 10 % MOD + dp[i][0] * tNum % MOD) % MOD) %= MOD;
            }
            else if (sNum < tNum)
            {
                (dp[i + 1][1] += dp[i][1]) %= MOD;
                (sum[i + 1][1] += (sum[i][1] * 10 % MOD + dp[i][1] * tNum % MOD) % MOD) %= MOD;
            }
            else
            {
                (dp[i + 1][1] += dp[i][1]) %= MOD;
                (dp[i + 1][1] += dp[i][0]) %= MOD;
                (sum[i + 1][1] += (sum[i][1] * 10 % MOD + dp[i][1] * tNum % MOD) % MOD) %= MOD;
                (sum[i + 1][1] += (sum[i][0] * 10 % MOD + dp[i][0] * tNum % MOD) % MOD) %= MOD;
            }
        }
        else
        {
            for (ll j = 0; j <= 9; j++)
            {
                tNum = j;
                if (sNum == tNum)
                {
                    (dp[i + 1][0] += dp[i][0]) %= MOD;
                    (dp[i + 1][1] += dp[i][1]) %= MOD;
                    (sum[i + 1][1] += (sum[i][1] * 10 % MOD + dp[i][1] * tNum % MOD) % MOD) %= MOD;
                    (sum[i + 1][0] += (sum[i][0] * 10 % MOD + dp[i][0] * tNum % MOD) % MOD) %= MOD;
                }
                else if (sNum < tNum)
                {
                    (dp[i + 1][1] += dp[i][1]) %= MOD;
                    (sum[i + 1][1] += (sum[i][1] * 10 % MOD + dp[i][1] * tNum % MOD) % MOD) %= MOD;
                }
                else
                {
                    (dp[i + 1][1] += dp[i][1]) %= MOD;
                    (dp[i + 1][1] += dp[i][0]) %= MOD;
                    (sum[i + 1][1] += (sum[i][1] * 10 % MOD + dp[i][1] * tNum % MOD) % MOD) %= MOD;
                    (sum[i + 1][1] += (sum[i][0] * 10 % MOD + dp[i][0] * tNum % MOD) % MOD) %= MOD;
                }
            }
        }
    }
    cout << (sum[n][0] + sum[n][1]) % MOD << endl;
}
accuracy: 1
time_ms: 10
memory_kb: 9688
final_rank: 4

code_snippet: /*

                   _ooOoo_
                  o8888888o
                  88" . "88
                  (| -_- |)
                  O\  =  /O
               ____/`---'\____
             .'  \\|     |//  `.
            /  \\|||  :  |||//  \
           /  _||||| -:- |||||-  \
           |   | \\\  -  /// |   |
           | \_|  ''\---/''  |   |
           \  .-\__  `-`  ___/-. /
         ___`. .'  /--.--\  `. . __
      ."" '<  `.___\_<|>_/___.'  >'"".
     | | :  `- \`.;`\ _ /`;.`/ - ` : | |
     \  \ `-.   \_ __\ /__ _/   .-` /  /
======`-.____`-.___\_____/___.-`____.-'======
                   `=---='
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
                    prayer
*/

// g++ -std=c++11 a.cpp
#include<iostream>
#include<vector>
#include<string>
#include<algorithm>
#include<map>
#include<set>
#include<unordered_map>
#include<utility>
#include<cmath>
#include<random>
#include<cstring>
#include<queue>
#include<stack>
#include<bitset>
#include<cstdio>
#include<sstream>
#include<iomanip>
#include<assert.h>
#include<typeinfo>
#define loop(i,a,b) for(long long i=a;i<b;i++)
#define rep(i,a) loop(i,0,a)
#define FOR(i,a) for(auto i:a)
#define pb push_back
#define all(in) in.begin(),in.end()
#define shosu(x) fixed<<setprecision(x)
#define show1d(v) {rep(_,v.size())cout<<" "<<v[_];cout<<endl;}
#define show2d(v) {rep(__,v.size())show1d(v[__]);}
using namespace std;
//kaewasuretyuui
typedef long long ll;
#define int ll
typedef int Def;
typedef pair<Def,Def> pii;
typedef vector<Def> vi;
typedef vector<vi> vvi;
typedef vector<pii> vp;
typedef vector<vp> vvp;
typedef vector<string> vs;
typedef vector<double> vd;
typedef vector<vd> vvd;
typedef pair<Def,pii> pip;
typedef vector<pip>vip;
#define mt make_tuple
typedef tuple<int,int,int,int> tp;
typedef vector<tp> vt;
template<typename A,typename B>bool cmin(A &a,const B &b){return a>b?(a=b,true):false;}
template<typename A,typename B>bool cmax(A &a,const B &b){return a<b?(a=b,true):false;}
const double PI=acos(-1);
const double EPS=1e-9;
Def inf = sizeof(Def) == sizeof(long long) ? 2e18 : 1e9+10;
#define yes cout<<"Yes\n"
#define no cout<<"No\n"

template< typename T >
istream &operator>>(istream &is, vector< T > &v) {
  for(T &in : v) is >> in;
  return is;
}

int dp[200020][2],ok[200020][2];
signed main(){
	ios::sync_with_stdio(false);
	cin.tie(0);

    string s,t;
    cin>>s>>t;
    int MOD=1000000007;
    ok[0][0]=1;
    rep(i,s.size())rep(j,2)rep(x,10)if(t[i]=='?'||t[i]-'0'==x){
        int I=i+1,J=j|s[i]-'0'>x;
        if(!J&&s[i]-'0'<x)continue;
        // cout<<i<<" "<<j<<" "<<x<<" "<<dp[i][j]<<" "<<I<<" "<<J<<endl;
        (ok[I][J]+=ok[i][j])%=MOD;
        (dp[I][J]+=dp[i][j]*10+ok[i][j]*x%MOD)%=MOD;
    }
    cout<<(dp[s.size()][0]+dp[s.size()][1])%MOD<<endl;
}
accuracy: 1
time_ms: 10
memory_kb: 9784
final_rank: 7

code_snippet: #include <bits/stdc++.h>
using namespace std;

typedef long long ll;
constexpr ll MOD = ll(1e9+7);

ll dp[200005][2][2];

int main(){
    string s, t;
    cin >> s >> t;
    int n = s.size();
    dp[0][0][1] = 1;
    for(int i=0;i<n;i++){
        int sd = s[i]-'0';
        if(t[i]=='?'){
            for(int j=0;j<2;j++){
                for(int d=0;d<=(j?9:sd);d++){
                    dp[i+1][j||(sd>d)][0] += dp[i][j][0] * 10 + dp[i][j][1] * d;
                    dp[i+1][j||(sd>d)][0] %= MOD;
                    dp[i+1][j||(sd>d)][1] += dp[i][j][1];
                    dp[i+1][j||(sd>d)][1] %= MOD;
                }
            }
        }
        else{
            int td = t[i]-'0';
            for(int j=0;j<2;j++){
                if(sd < td &&j == 0) continue;
                dp[i+1][j||(sd>td)][0] += dp[i][j][0] * 10 + dp[i][j][1] * td;
                dp[i+1][j||(sd>td)][0] %= MOD;
                dp[i+1][j||(sd>td)][1] += dp[i][j][1];
                dp[i+1][j||(sd>td)][1] %= MOD;
            
            }
        }
    }
    ll ans = 0;
    ans = (dp[n][1][0] + dp[n][0][0]) % MOD;
    cout << ans << endl;
    return 0;
}
accuracy: 1
time_ms: 10
memory_kb: 9720
final_rank: 6

code_snippet: #include <bits/stdc++.h>
using namespace std;
#define REP(i,n) for (int i=0;i<(n);i++)
#define REP2(i,m,n) for (int i=m;i<(n);i++)
typedef long long ll;

const ll MOD = 1000000007;
ll dp[201010][2];
ll dp2[201010][2];
ll base[201010];

void solve() {
    string S, T;
    cin >> S >> T;
    int N = S.size();

    base[0] = 1;
    REP(i, N) base[i+1] = base[i] * 10 % MOD;

    dp2[0][0] = 1;

    REP(i, N) REP(j, 2) {
        ll b = base[N-i-1];
        REP(nd, 10) {
            if (T[i] != '?' && nd != T[i] - '0') continue;
            if (!j && nd > S[i] - '0') continue;
            (dp[i+1][j||(nd<S[i]-'0')] += (dp[i][j] + b * nd % MOD * dp2[i][j] % MOD)) %= MOD;
            (dp2[i+1][j||(nd<S[i]-'0')] += dp2[i][j]) %= MOD;
        }
    }

    cout << (dp[N][0] + dp[N][1]) % MOD << endl;
}

int main() {
    cin.tie(0);
    ios::sync_with_stdio(false);
    solve();
}
accuracy: 1
time_ms: 10
memory_kb: 11284
final_rank: 9

code_snippet: #include <iostream>
#include <string>
#include <algorithm>
#define rep(i, n) for(i = 0; i < n; i++)
#define int long long
using namespace std;

int mod = 1000000007;
string s;
string t;
int dpCnt[200001][2];
int dpSum[200001][2];

signed main() {
	int i, j, k;
	
	cin >> s >> t;
	int n = s.length();
	
	dpCnt[0][0] = 1;
	rep(i, n) {
		rep(j, 2) {
			rep(k, 10) {
				if (t[i] != '?' && k != (t[i] - '0')) continue;
				if (j == 0 && k > (s[i] - '0')) continue;
				int nj = (j || (k < (s[i] - '0')));
				(dpCnt[i + 1][nj] += dpCnt[i][j]) %= mod;
				(dpSum[i + 1][nj] += 10 * dpSum[i][j] + dpCnt[i][j] * k) %= mod;
			}
		}
	}
	
	int ans = dpSum[n][0] + dpSum[n][1];
	cout << ans % mod << endl;
	return 0;
}
accuracy: 1
time_ms: 30
memory_kb: 9592
final_rank: 12