Buggy python submission (verdict: Time Limit Exceeded):
S = input()[::-1]
N = len(S)

"""
    例： S = '31415926535'
        S[3:8] = '15926535' が 2019 で割り切れるかどうか？
     <=> S[3:-1] - S[8:-1] が 2019 で割り切れるかどうか
     <=> S[3:-1] % 2019 == S[8:-1] % 2019 か
    よって、2019で割ったときの異なるあまりをそれぞれカウントすればよい
"""

mod_cnts = [0] * 2019
mod_cnts[0] = 1 # 累積和のはじめ
current_cusum, ans = 0, 0
# O(N)
# d = 1
for i in range(N):
# for s in S:
    s = S[i]
    current_cusum += (pow(10, i)% 2019) * int(s) # 累積和
    # current_cusum += d * int(s)
    current_cusum %= 2019
    mod_cnts[current_cusum] += 1

    # d *= 10 % 2019

# O(2019)
for cnt in mod_cnts:
    ans += cnt * (cnt - 1) // 2 # n_C_2 2つ選ぶ組み合わせ
 
print(ans)


Fixed submission:
S = input()
N = len(S)

num = [0] * 2019
num[0] = 1
now, ans = 0, 0
_10 = 1

for i in range(N-1, -1, -1):
    now = (now + int(S[i]) * _10) % 2019
    _10 *= 10
    _10 %= 2019
    ans += num[now]
    num[now] += 1
 
print(ans)

Buggy python submission (verdict: Time Limit Exceeded):
S = input()[::-1]
N = len(S)

"""
    例： S = '31415926535'
        S[3:8] = '15926535' が 2019 で割り切れるかどうか？
     <=> S[3:-1] - S[8:-1] が 2019 で割り切れるかどうか
     <=> S[3:-1] % 2019 == S[8:-1] % 2019 か
    よって、2019で割ったときの異なるあまりをそれぞれカウントすればよい
"""

mod_cnts = [0] * 2019
mod_cnts[0] = 1 # 累積和のはじめ
current_cusum, ans = 0, 0
# O(N)
d = 1
# for i in range(N):
for s in S:
    # s = S[i]
    # current_cusum += pow(10, i) * int(s) # 累積和
    current_cusum += d * int(s)
    current_cusum %= 2019
    mod_cnts[current_cusum] += 1

    d *= 10 % 2019

# O(2019)
for cnt in mod_cnts:
    ans += cnt * (cnt - 1) // 2 # n_C_2 2つ選ぶ組み合わせ
 
print(ans)


Fixed submission:
S = input()
N = len(S)

num = [0] * 2019
num[0] = 1
now, ans = 0, 0
_10 = 1

for i in range(N-1, -1, -1):
    now = (now + int(S[i]) * _10) % 2019
    _10 *= 10
    _10 %= 2019
    ans += num[now]
    num[now] += 1
 
print(ans)

Buggy python submission (verdict: Time Limit Exceeded):
S = input()[::-1]
N = len(S)

"""
    例： S = '31415926535'
        S[3:8] = '15926535' が 2019 で割り切れるかどうか？
     <=> S[3:-1] - S[8:-1] が 2019 で割り切れるかどうか
     <=> S[3:-1] % 2019 == S[8:-1] % 2019 か
    よって、2019で割ったときの異なるあまりをそれぞれカウントすればよい
"""

mod_cnts = [0] * 2019
mod_cnts[0] = 1 # 累積和のはじめ
current_cusum, ans = 0, 0
# O(N)
d = 1
# for i in range(N):
for s in S:
    # s = S[i]
    # current_cusum += pow(10, i) * int(s) # 累積和
    current_cusum += d * int(s)
    current_cusum %= 2019
    mod_cnts[current_cusum] += 1

    d *= 10

# O(2019)
for cnt in mod_cnts:
    ans += cnt * (cnt - 1) // 2 # n_C_2 2つ選ぶ組み合わせ
 
print(ans)


Fixed submission:
S = input()
N = len(S)

num = [0] * 2019
num[0] = 1
now, ans = 0, 0
_10 = 1

for i in range(N-1, -1, -1):
    now = (now + int(S[i]) * _10) % 2019
    _10 *= 10
    _10 %= 2019
    ans += num[now]
    num[now] += 1
 
print(ans)

Buggy python submission (verdict: Time Limit Exceeded):
S = input()[::-1]
N = len(S)

"""
    例： S = '31415926535'
        S[3:8] = '15926535' が 2019 で割り切れるかどうか？
     <=> S[3:-1] - S[8:-1] が 2019 で割り切れるかどうか
     <=> S[3:-1] % 2019 == S[8:-1] % 2019 か
    よって、2019で割ったときの異なるあまりをそれぞれカウントすればよい
"""

mod_cnts = [0] * 2019
mod_cnts[0] = 1 # 累積和のはじめ
current_cusum, ans = 0, 0
for i in range(N):
    s = S[i]
    current_cusum += pow(10, i) * int(s) # 累積和
    current_cusum %= 2019
    mod_cnts[current_cusum] += 1

for cnt in mod_cnts:
    ans += cnt * (cnt - 1) // 2 # n_C_2 2つ選ぶ組み合わせ
 
print(ans)


Fixed submission:
S = input()
N = len(S)

num = [0] * 2019
num[0] = 1
now, ans = 0, 0
_10 = 1

for i in range(N-1, -1, -1):
    now = (now + int(S[i]) * _10) % 2019
    _10 *= 10
    _10 %= 2019
    ans += num[now]
    num[now] += 1
 
print(ans)

Buggy python submission (verdict: Time Limit Exceeded):
S = input()[::-1]
N = len(S)

"""
    例： S = '31415926535'
        S[3:8] = '15926535' が 2019 で割り切れるかどうか？
     <=> S[3:-1] - S[8:-1] が 2019 で割り切れるかどうか
     <=> S[3:-1] % 2019 == S[8:-1] % 2019 か
    よって、2019で割ったときの異なるあまりをそれぞれカウントすればよい
"""

mod_cnts = [0] * 2019
mod_cnts[0] = 1 # 累積和のはじめ
current_cusum, ans = 0, 0
for i in range(N):
    s = S[i]
    current_cusum += pow(10, i) * int(s) # 累積和
    current_cusum %= 2019
    mod_cnts[current_cusum] += 1

for cnt in mod_cnts:
    ans += cnt * (cnt - 1) // 2 # n_C_2 2つ選ぶ組み合わせ
 
print(ans)


Fixed submission:
S = input()
N = len(S)

num = [0] * 2019
num[0] = 1
now, ans = 0, 0
_10 = 1

for i in range(N-1, -1, -1):
    now = (now + int(S[i]) * _10) % 2019
    _10 *= 10
    _10 %= 2019
    ans += num[now]
    num[now] += 1
 
print(ans)

Buggy python submission (verdict: Time Limit Exceeded):
S = input()
N = len(S)

cnt = 0
for i in range(N - 3):
    for j in range(i + 4, N + 1):
        if int(S[i:j]) % 2019 == 0:
            # print(i, j)
            cnt += 1
print(cnt)


Fixed submission:
S = input()
N = len(S)

num = [0] * 2019
num[0] = 1
now, ans = 0, 0
_10 = 1

for i in range(N-1, -1, -1):
    now = (now + int(S[i]) * _10) % 2019
    _10 *= 10
    _10 %= 2019
    ans += num[now]
    num[now] += 1
 
print(ans)

Buggy python submission (verdict: Time Limit Exceeded):
S = input()
N = len(S)

cnt = 0
for i in range(N - 3):
    for j in range(i + 4, N + 1):
        if int(S[i:j]) % 2019 == 0:
            # print(i, j)
            cnt += 1
print(cnt)


Fixed submission:
S = input()
N = len(S)

num = [0] * 2019
num[0] = 1
now, ans = 0, 0
_10 = 1

for i in range(N-1, -1, -1):
    now = (now + int(S[i]) * _10) % 2019
    _10 *= 10
    _10 %= 2019
    ans += num[now]
    num[now] += 1
 
print(ans)