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 で割った余りを求めてください。

Solution in Python3 (judge verdict: Accepted)

#!usr/bin/env python3
from collections import defaultdict,deque
from heapq import heappush, heappop
import sys
import math
import bisect
import random
def LI(): return [int(x) for x in sys.stdin.readline().split()]
def I(): return int(sys.stdin.readline())
def LS():return [list(x) for x in sys.stdin.readline().split()]
def S():
    res = list(sys.stdin.readline())
    if res[-1] == "\n":
        return res[:-1]
    return res
def IR(n):
    return [I() for i in range(n)]
def LIR(n):
    return [LI() for i in range(n)]
def SR(n):
    return [S() for i in range(n)]
def LSR(n):
    return [LS() for i in range(n)]

sys.setrecursionlimit(1000000)
mod = 1000000007


def solve():
    s = list(map(int, input()))
    t = list(input())
    n = len(t)
    for i in range(n):
        if t[i].isdecimal():
            t[i] = int(t[i])
    dp = [[[0]*2 for j in range(2)] for i in range(n+1)]
    dp[0][0] = [1,0]
    p = [pow(10,i,mod) for i in range(n)]
    for i in range(n):
        ni = i+1
        for j in range(2):
            if t[i] == "?":
                x = 9 if j else s[i]
                for d in range(x+1):
                    nj = j|(d < s[i])
                    dp[ni][nj][0] += dp[i][j][0]
                    dp[ni][nj][1] += dp[i][j][0]*d+10*dp[i][j][1]
                    dp[ni][nj][0] %= mod
                    dp[ni][nj][1] %= mod
            else:
                d = t[i]
                nj = j|(d < s[i])
                if d <= s[i]:
                    dp[ni][nj][0] += dp[i][j][0]
                    dp[ni][nj][1] += dp[i][j][0]*d+10*dp[i][j][1]
                    dp[ni][nj][0] %= mod
                    dp[ni][nj][1] %= mod
                else:
                    if nj:
                        dp[ni][nj][0] += dp[i][j][0]
                        dp[ni][nj][1] += dp[i][j][0]*d+10*dp[i][j][1]
                        dp[ni][nj][0] %= mod
                        dp[ni][nj][1] %= mod

    print((dp[-1][0][1]+dp[-1][1][1])%mod)
    return


if __name__ == "__main__":
    solve()