Problem:


Score : 500 points

Problem Statement

You are given two integer sequences S and T of length N and M, respectively, both consisting of integers between 1 and 10^5 (inclusive).

In how many pairs of a subsequence of S and a subsequence of T do the two subsequences are the same in content?

Here the subsequence of A is a sequence obtained by removing zero or more elements from A and concatenating the remaining elements without changing the order.

For both S and T, we distinguish two subsequences if the sets of the indices of the removed elements are different, even if the subsequences are the same in content.

Since the answer can be tremendous, print the number modulo 10^9+7.

Constraints

1 \leq N, M \leq 2 \times 10^3

The length of S is N.

The length of T is M.     

1 \leq S_i, T_i \leq 10^5

All values in input are integers.

Input

Input is given from Standard Input in the following format:

N M
S_1 S_2 ... S_{N-1} S_{N}
T_1 T_2 ... T_{M-1} T_{M}

Output

Print the number of pairs of a subsequence of S and a subsequence of T such that the subsequences are the same in content, modulo 10^9+7.

Sample Input 1

2 2
1 3
3 1

Sample Output 1

3

S has four subsequences: (), (1), (3), (1, 3).

T has four subsequences: (), (3), (1), (3, 1).

There are 1 \times 1 pair of subsequences in which the subsequences are both (), 1 \times 1 pair of subsequences in which the subsequences are both (1), and 1 \times 1 pair of subsequences in which the subsequences are both (3), for a total of three pairs.

Sample Input 2

2 2
1 1
1 1

Sample Output 2

6

S has four subsequences: (), (1), (1), (1, 1).

T has four subsequences: (), (1), (1), (1, 1).

There are 1 \times 1 pair of subsequences in which the subsequences are both (), 2 \times 2 pairs of subsequences in which the subsequences are both (1), and 1 \times 1 pair of subsequences in which the subsequences are both (1,1), for a total of six pairs.
Note again that we distinguish two subsequences if the sets of the indices of the removed elements are different, even if the subsequences are the same in content.

Sample Input 3

4 4
3 4 5 6
3 4 5 6

Sample Output 3

16

Sample Input 4

10 9
9 6 5 7 5 9 8 5 6 7
8 6 8 5 5 7 9 9 7

Sample Output 4

191

Sample Input 5

20 20
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1

Sample Output 5

846527861

Be sure to print the number modulo 10^9+7.



Sample input:
2 2
1 3
3 1


Sample output:
3

Submission status: Accepted

Solution code:
import subprocess
import gzip, base64, os
import stat

gz = b'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'
bin = gzip.decompress(base64.b64decode(gz))
p = os.path.dirname(__file__)
pymain = os.path.join(p, "a.out")
with open(pymain, "wb") as f:
    f.write(bin)
os.chmod(pymain, stat.S_IRUSR | stat.S_IWUSR | stat.S_IXUSR)
if p == "":
    pymain = "./" + pymain
subprocess.call(pymain)


# compiled by pythran
'''
#pythran export main2()


def calc(S, T, a):
    MOD = 10 ** 9 + 7
    for i in range(1, len(S) + 1):
        for j in range(1, len(T) + 1):
            a[i][j] = (a[i - 1][j] + a[i][j - 1] -
                       (a[i - 1][j - 1] if S[i - 1] != T[j - 1] else 0)) % MOD


def main2():
    stdin = open('/dev/stdin')
    N, M = [int(x) for x in stdin.readline().split()]
    S = [int(x) for x in stdin.readline().split()]
    T = [int(x) for x in stdin.readline().split()]
    a = [[1] * (M + 1) for x in range(N + 1)]
    calc(S, T, a)
    print(a[N][M])
'''

Submission status: Accepted

Solution code:
# numpyでかいてもTLEした。
# pypyでlistでかくととおる？

#import numpy as np
N,M = list(map(int, input().split()))
S = list(map(int, input().split()))
T = list(map(int, input().split()))
mod = int(1e9+7)
"""
dp[i][j] : S の i 文字目までと T の j 文字目までを考慮し、
この 2 文字 (S[i] と T[j]）をペアにするときの場合の数とすると、

dp[i][j] = (sum(dp[1:i-1][1:j-1]) + 1 if S[i] == T[j] else 0)
このsumの部分をどうもとめるか。

最終的な答えはsum(dp[:][:])。

2-D cumsumをつかう
i,j = 0のときにきをつけて
DS[i][j] = DS[i-1][j] + DS[i][j-1] - DS[i-1][j-1] + dp[i][j]
"""

dp = [[ 0 for _ in range(M)] for _ in range(N)]
DS = [[ 0 for _ in range(M+1)] for _ in range(N+1)]

for i in range(N):
  for j in range(M):
    if S[i] != T[j]:
      dp[i][j] = 0
    else:
      dp[i][j] += 1
      dp[i][j] += DS[i-1][j-1]
      dp[i][j] %= mod
    DS[i][j] = DS[i-1][j] + DS[i][j-1] - DS[i-1][j-1] + dp[i][j]
    DS[i][j] %= mod
print(DS[-2][-2]+1)
#print(dp)
#print(DS)

Submission status: Accepted

Solution code:
# https://atcoder.jp/contests/abc130/tasks/abc130_e
"""
タグ: LCS、二次元累積和
"""
import sys
input = sys.stdin.readline
MOD = 10**9 + 7

N, M = map(int, input().split())
S = list(map(int, input().split()))
T = list(map(int, input().split()))
dp = [[0]*(M+1) for _ in range(N+1)]
cum = [[0] * (M + 1) for _ in range(N + 1)]
for i in range(N):
    for j in range(M):
        if S[i]==T[j]:
            dp[i][j] += cum[i][j] + 1
            dp[i][j]%=MOD
        cum[i + 1][j + 1] = cum[i][j + 1] + cum[i + 1][j] - cum[i][j] + dp[i][j]
        cum[i + 1][j + 1]%=MOD
print(cum[N][M]+1)

Submission status: Accepted

Solution code:
MOD = 10**9 + 7
N, M = map(int, input().split())
S = [int(i) for i in input().split()]
T = [int(i) for i in input().split()]

dp = [[0 for j in range(2010)] for i in range(2010)]
dp[0][0] = 1
for s in range(N+1):
    for t in range(M+1):
        if 0 < s and 0 < t and S[s-1] == T[t-1]:
            dp[s][t] += dp[s-1][t-1]
        if 0 < s:
            dp[s][t] += dp[s-1][t]
        if 0 < t:
            dp[s][t] += dp[s][t-1]
        if 0 < s and 0 < t:
            dp[s][t] -= dp[s-1][t-1]
        dp[s][t] %= MOD
print(dp[N][M])

Submission status: Accepted

Solution code:
MOD=10**9+7
INF=float('inf')
N,M=map(int,input().split())
S=list(map(int,input().split()))
T=list(map(int,input().split()))
dp=[[-INF]*(M+1) for i in range(N+1)]
dp[0][0]=1
for i in range(N+1):
    dp[i][0]=1
for j in range(M+1):
    dp[0][j]=1
for i in range(N):
    for j in range(M):
        if S[i]==T[j]:
            dp[i+1][j+1]=(dp[i][j+1]+dp[i+1][j])%MOD
        else:
            dp[i+1][j+1]=(dp[i][j+1]+dp[i+1][j]-dp[i][j]+MOD)%MOD
print(dp[N][M])

Submission status: Accepted

Solution code:
def getN():
    return int(input())
def getNM():
    return map(int, input().split())
def getList():
    return list(map(int, input().split()))
def getArray(intn):
    return [int(input()) for i in range(intn)]
def input():
    return sys.stdin.readline().rstrip()
def rand_N(ran1, ran2):
    return random.randint(ran1, ran2)
def rand_List(ran1, ran2, rantime):
    return [random.randint(ran1, ran2) for i in range(rantime)]
def rand_ints_nodup(ran1, ran2, rantime):
  ns = []
  while len(ns) < rantime:
    n = random.randint(ran1, ran2)
    if not n in ns:
      ns.append(n)
  return sorted(ns)

def rand_query(ran1, ran2, rantime):
  r_query = []
  while len(r_query) < rantime:
    n_q = rand_ints_nodup(ran1, ran2, 2)
    if not n_q in r_query:
      r_query.append(n_q)
  return sorted(r_query)

from collections import defaultdict, deque, Counter
from sys import exit
from decimal import *
import heapq
import math
from fractions import gcd
import random
import string
import copy
from itertools import combinations, permutations, product
from operator import mul, itemgetter
from functools import reduce
from bisect import bisect_left, bisect_right

import sys
sys.setrecursionlimit(1000000000)
mod = 10 ** 9 + 7

#############
# Main Code #
#############

N, M = getNM()
S = getList()
N_s = len(S)
T = getList()
N_t = len(T)

dp = [[0] * (N_s + 1) for i in range(N_t + 1)]
dp[0][0] = 0

for i in range(N_t):
    for j in range(N_s):
        # 基礎 dp[i][j] + Sを伸ばして増えた分 + Tを伸ばして増えた分
        dp[i + 1][j + 1] = (dp[i + 1][j] + dp[i][j + 1] - dp[i][j]) % mod
        if S[j] == T[i]:
            # dp[i][j]の通りのそれぞれの末尾に(S[i], T[i])をつけることで
            # dp[i][j]通り（と空に(S[i], T[i])をつけた）分新しいのが作れる
            dp[i + 1][j + 1] = (dp[i + 1][j + 1] + dp[i][j] + 1) % mod
print((dp[N_t][N_s] + 1) % mod)

Submission status: Accepted

Solution code:

"""
問題: https://atcoder.jp/contests/abc130/tasks/abc130_e
解説: https://drken1215.hatenablog.com/entry/2019/06/21/230200

共通部分列を数え上げる問題．
"""


def main1():
    """LCS (Longest Common Sequence)を改良する．

    LCSでは最長部分列の長さを求めるが，今回は個数を求める．
    重複して数えている分を引けば良い．
    """
    N, M = map(int, input().split())
    S = list(map(int, input().split()))
    T = list(map(int, input().split()))

    dp = [[0] * (M + 1) for _ in range(N + 1)]
    MOD = 10 ** 9 + 7

    for i in range(N + 1):
        dp[i][0] = 1

    for j in range(M + 1):
        dp[0][j] = 1

    for i in range(N):
        for j in range(M):
            if S[i] == T[j]:
                dp[i + 1][j + 1] += dp[i][j]
            dp[i + 1][j + 1] += dp[i][j + 1] + dp[i + 1][j] - dp[i][j]
            dp[i + 1][j + 1] %= MOD

    print(dp[-1][-1])


def main2():
    N, M = map(int, input().split())
    S = list(map(int, input().split()))
    T = list(map(int, input().split()))

    dp = [[0] * (M + 1) for _ in range(N + 1)]
    sdp = [[0] * (M + 2) for _ in range(N + 2)]
    MOD = 10 ** 9 + 7

    dp[0][0] = 1
    sdp[1][1] = 1

    for i in range(N + 1):
        for j in range(M + 1):
            if i == 0 and j == 0:
                continue
            if i >= 1 and j >= 1 and S[i - 1] == T[j - 1]:
                dp[i][j] = sdp[i][j]
            sdp[i + 1][j + 1] = (sdp[i + 1][j] + sdp[i][j + 1] - sdp[i][j]
                                 + dp[i][j])
            sdp[i + 1][j + 1] %= MOD

    print(sdp[-1][-1])


if __name__ == "__main__":
    # main1()
    main2()

Submission status: Accepted

Solution code:
n,m=map(int,input().split())
s=list(map(int,input().split()))
t=list(map(int,input().split()))
mod=10**9+7
dp=[1]*(m+1)
for i in range(n):
    ndp=[0]*(m+1)
    ndp[0]=1
    for j in range(m):
        if s[i]==t[j]:
            ndp[j+1]=(ndp[j]+dp[j+1])%mod
        else:
            ndp[j+1]=(ndp[j]+dp[j+1]-dp[j])%mod
    dp=ndp
print(dp[-1])

Submission status: Accepted

Solution code:
# dp[i][j] SとTの最後の文字を採用するような文字列の個数。これにより各DPテーブルの値が排反になる。元の文字列の最後を必ず採用するので
N, M = map(int, input().split())
S = list(map(int, input().split()))
T = list(map(int, input().split()))
MOD = 10**9 + 7
dp = [[0] * (M + 2) for _ in range(N + 2)]
sdp = [[0] * (M + 2) for _ in range(N + 2)]
dp[0][0] = 1
sdp[1][1] = 1
for i in range(N + 1):
    for j in range(M + 1):
        if i - 1 >= 0 and j - 1 >= 0 and S[i - 1] == T[j - 1]:
            dp[i][j] = sdp[i][j]
        sdp[i + 1][j + 1] = sdp[i + 1][j] + sdp[i][j + 1] - sdp[i][j] + dp[i][j]
        sdp[i + 1][j + 1] %= MOD
        sdp[i + 1][j + 1] %= MOD
print(sdp[N + 1][M + 1])

Submission status: Accepted

Solution code:
mod = 1000000007

n, m = map(int, input().split())
s = list(map(int, input().split()))
t = list(map(int, input().split()))

dp = [[0] * (m+1) for _ in range(n+1)]
dp[0][0] = 0
for i in range(1, n+1):
    for j in range(1, m+1):
        dp[i][j] = (dp[i][j-1] + dp[i-1][j] - dp[i-1][j-1]) % mod
        if s[i-1] == t[j-1]: 
            dp[i][j] = (dp[i][j] + dp[i-1][j-1] + 1) % mod
print((dp[n][m]+1) % mod)