Buggy python submission (verdict: Time Limit Exceeded):
from collections import deque

S = list(input())

mod = [0] * (2019+1)

tmp = deque([])
for i in range(1, len(S)+1):
    tmp.appendleft(S[-i])
    mod[int("".join(tmp)) % 2019] += 1

ans = mod[0]
for i in range(1, 2020):
    if mod[i] >= 2:
        ans += (mod[i] * (mod[i]-1)) // 2
print(ans)

Fixed submission:
S = input()

n_i_to_j_mod = [0] * (2019+1) # 2019で割った余りがiになるようなSの部分連続文字列の個数
i_to_end_mod = [0] * (len(S)+1) # S[-i:](Sの後方i文字)を2019で割ったときの余り

for i in range(1, len(S)+1):
    if i == 1:
        i_to_end_mod[1] = int(S[-1]) % 2019
    else:
        i_to_end_mod[i] = (i_to_end_mod[i-1] + int(S[-i]) * pow(10, i-1, 2019)) % 2019
    n_i_to_j_mod[i_to_end_mod[i]] += 1

ans = n_i_to_j_mod[0] + (n_i_to_j_mod[0] * (n_i_to_j_mod[0]-1))//2
for i in range(1, 2019):
    if n_i_to_j_mod[i] >= 2:
        ans += (n_i_to_j_mod[i] * (n_i_to_j_mod[i]-1)) // 2
print(ans)

Buggy python submission (verdict: Time Limit Exceeded):
from collections import deque

S = list(input())

mod = [0] * (2019+1)

tmp = deque([])
for i in range(1, len(S)+1):
    tmp.appendleft(S[-i])
    mod[int("".join(tmp)) % 2019] += 1

ans = mod[0]
for i in range(1, 2020):
    if mod[i] >= 2:
        ans += (mod[i] * (mod[i]-1)) // 2
print(ans)

Fixed submission:
S = input()

n_i_to_j_mod = [0] * (2019+1) # 2019で割った余りがiになるようなSの部分連続文字列の個数
i_to_end_mod = [0] * (len(S)+1) # S[-i:](Sの後方i文字)を2019で割ったときの余り

for i in range(1, len(S)+1):
    if i == 1:
        i_to_end_mod[1] = int(S[-1]) % 2019
    else:
        i_to_end_mod[i] = (i_to_end_mod[i-1] + int(S[-i]) * pow(10, i-1, 2019)) % 2019
    n_i_to_j_mod[i_to_end_mod[i]] += 1

ans = n_i_to_j_mod[0] + (n_i_to_j_mod[0] * (n_i_to_j_mod[0]-1))//2
for i in range(1, 2019):
    if n_i_to_j_mod[i] >= 2:
        ans += (n_i_to_j_mod[i] * (n_i_to_j_mod[i]-1)) // 2
print(ans)

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

mod = [0] * (2019+1)

tmp = ""
for i in range(1, len(S)+1):
    tmp = S[-i] + str(tmp)
    mod[int(tmp) % 2019] += 1

ans = mod[0]
for i in range(1, 2020):
    if mod[i] >= 2:
        ans += (mod[i] * (mod[i]-1)) // 2
print(ans)

Fixed submission:
S = input()

n_i_to_j_mod = [0] * (2019+1) # 2019で割った余りがiになるようなSの部分連続文字列の個数
i_to_end_mod = [0] * (len(S)+1) # S[-i:](Sの後方i文字)を2019で割ったときの余り

for i in range(1, len(S)+1):
    if i == 1:
        i_to_end_mod[1] = int(S[-1]) % 2019
    else:
        i_to_end_mod[i] = (i_to_end_mod[i-1] + int(S[-i]) * pow(10, i-1, 2019)) % 2019
    n_i_to_j_mod[i_to_end_mod[i]] += 1

ans = n_i_to_j_mod[0] + (n_i_to_j_mod[0] * (n_i_to_j_mod[0]-1))//2
for i in range(1, 2019):
    if n_i_to_j_mod[i] >= 2:
        ans += (n_i_to_j_mod[i] * (n_i_to_j_mod[i]-1)) // 2
print(ans)

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

mod = [0] * (2019+1)

tmp = ""
for i in range(1, len(S)+1):
    tmp = S[-i] + str(tmp)
    mod[int(tmp) % 2019] += 1

ans = mod[0]
for i in range(1, 2020):
    if mod[i] >= 2:
        ans += (mod[i] * (mod[i]-1)) // 2
print(ans)

Fixed submission:
S = input()

n_i_to_j_mod = [0] * (2019+1) # 2019で割った余りがiになるようなSの部分連続文字列の個数
i_to_end_mod = [0] * (len(S)+1) # S[-i:](Sの後方i文字)を2019で割ったときの余り

for i in range(1, len(S)+1):
    if i == 1:
        i_to_end_mod[1] = int(S[-1]) % 2019
    else:
        i_to_end_mod[i] = (i_to_end_mod[i-1] + int(S[-i]) * pow(10, i-1, 2019)) % 2019
    n_i_to_j_mod[i_to_end_mod[i]] += 1

ans = n_i_to_j_mod[0] + (n_i_to_j_mod[0] * (n_i_to_j_mod[0]-1))//2
for i in range(1, 2019):
    if n_i_to_j_mod[i] >= 2:
        ans += (n_i_to_j_mod[i] * (n_i_to_j_mod[i]-1)) // 2
print(ans)

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

mod = [0] * (2019+1)

tmp = ""
for i in range(1, len(S)+1):
    tmp = int(S[-i] + str(tmp))
    mod[tmp % 2019] += 1

ans = mod[0]

for i in range(1, 2020):
    if mod[i] >= 2:
        ans += (mod[i] * (mod[i]-1)) // 2
print(ans)

Fixed submission:
S = input()

n_i_to_j_mod = [0] * (2019+1) # 2019で割った余りがiになるようなSの部分連続文字列の個数
i_to_end_mod = [0] * (len(S)+1) # S[-i:](Sの後方i文字)を2019で割ったときの余り

for i in range(1, len(S)+1):
    if i == 1:
        i_to_end_mod[1] = int(S[-1]) % 2019
    else:
        i_to_end_mod[i] = (i_to_end_mod[i-1] + int(S[-i]) * pow(10, i-1, 2019)) % 2019
    n_i_to_j_mod[i_to_end_mod[i]] += 1

ans = n_i_to_j_mod[0] + (n_i_to_j_mod[0] * (n_i_to_j_mod[0]-1))//2
for i in range(1, 2019):
    if n_i_to_j_mod[i] >= 2:
        ans += (n_i_to_j_mod[i] * (n_i_to_j_mod[i]-1)) // 2
print(ans)

Buggy python submission (verdict: Time Limit Exceeded):
import math
def naive_cmb(n, r):
    if r < 0 or r > n:
        return 0
    return (math.factorial(n) // math.factorial(r)) // math.factorial(n-r)

S = input()

mod = [0] * (2019+1)

tmp = ""
for i in range(1, len(S)+1):
    tmp = int(S[-i] + str(tmp))
    mod[tmp % 2019] += 1

ans = mod[0]

for i in range(1, 2020):
    if mod[i] >= 2:
        ans += naive_cmb(mod[i], 2)

print(ans)

Fixed submission:
S = input()

n_i_to_j_mod = [0] * (2019+1) # 2019で割った余りがiになるようなSの部分連続文字列の個数
i_to_end_mod = [0] * (len(S)+1) # S[-i:](Sの後方i文字)を2019で割ったときの余り

for i in range(1, len(S)+1):
    if i == 1:
        i_to_end_mod[1] = int(S[-1]) % 2019
    else:
        i_to_end_mod[i] = (i_to_end_mod[i-1] + int(S[-i]) * pow(10, i-1, 2019)) % 2019
    n_i_to_j_mod[i_to_end_mod[i]] += 1

ans = n_i_to_j_mod[0] + (n_i_to_j_mod[0] * (n_i_to_j_mod[0]-1))//2
for i in range(1, 2019):
    if n_i_to_j_mod[i] >= 2:
        ans += (n_i_to_j_mod[i] * (n_i_to_j_mod[i]-1)) // 2
print(ans)

Buggy python submission (verdict: Time Limit Exceeded):
import math
def naive_cmb(n, r):
    if r < 0 or r > n:
        return 0
    return (math.factorial(n) // math.factorial(r)) // math.factorial(n-r)

S = input()

mod = [0] * (2019+1)

tmp = ""
for i in range(1, len(S)+1):
    tmp = int(S[-i] + str(tmp))
    mod[tmp % 2019] += 1

ans = mod[0]

for i in range(1, 2020):
    if mod[i] >= 2:
        ans += naive_cmb(mod[i], 2)

print(ans)

Fixed submission:
S = input()

n_i_to_j_mod = [0] * (2019+1) # 2019で割った余りがiになるようなSの部分連続文字列の個数
i_to_end_mod = [0] * (len(S)+1) # S[-i:](Sの後方i文字)を2019で割ったときの余り

for i in range(1, len(S)+1):
    if i == 1:
        i_to_end_mod[1] = int(S[-1]) % 2019
    else:
        i_to_end_mod[i] = (i_to_end_mod[i-1] + int(S[-i]) * pow(10, i-1, 2019)) % 2019
    n_i_to_j_mod[i_to_end_mod[i]] += 1

ans = n_i_to_j_mod[0] + (n_i_to_j_mod[0] * (n_i_to_j_mod[0]-1))//2
for i in range(1, 2019):
    if n_i_to_j_mod[i] >= 2:
        ans += (n_i_to_j_mod[i] * (n_i_to_j_mod[i]-1)) // 2
print(ans)

Buggy python submission (verdict: Time Limit Exceeded):
import math
def naive_cmb(n, r):
    if r < 0 or r > n:
        return 0
    return (math.factorial(n) // math.factorial(r)) // math.factorial(n-r)

S = input()

mod = [0] * (2019+1)

for i in range(1, len(S)+1):
    mod[int(S[-i:]) % 2019] += 1

ans = mod[0]

for i in range(1, 2020):
    if mod[i] >= 2:
        ans += naive_cmb(mod[i], 2)

print(ans)

Fixed submission:
S = input()

n_i_to_j_mod = [0] * (2019+1) # 2019で割った余りがiになるようなSの部分連続文字列の個数
i_to_end_mod = [0] * (len(S)+1) # S[-i:](Sの後方i文字)を2019で割ったときの余り

for i in range(1, len(S)+1):
    if i == 1:
        i_to_end_mod[1] = int(S[-1]) % 2019
    else:
        i_to_end_mod[i] = (i_to_end_mod[i-1] + int(S[-i]) * pow(10, i-1, 2019)) % 2019
    n_i_to_j_mod[i_to_end_mod[i]] += 1

ans = n_i_to_j_mod[0] + (n_i_to_j_mod[0] * (n_i_to_j_mod[0]-1))//2
for i in range(1, 2019):
    if n_i_to_j_mod[i] >= 2:
        ans += (n_i_to_j_mod[i] * (n_i_to_j_mod[i]-1)) // 2
print(ans)

Buggy python submission (verdict: Time Limit Exceeded):
S = input()
b = set([2019*x for x in range(1, 200000//2019 + 1)])

ans = 0
for i in range(len(S)):
    for j in range(i+1, len(S)+1):
        if int(S[i:j]) in b:
            ans += 1
print(ans)

Fixed submission:
S = input()

n_i_to_j_mod = [0] * (2019+1) # 2019で割った余りがiになるようなSの部分連続文字列の個数
i_to_end_mod = [0] * (len(S)+1) # S[-i:](Sの後方i文字)を2019で割ったときの余り

for i in range(1, len(S)+1):
    if i == 1:
        i_to_end_mod[1] = int(S[-1]) % 2019
    else:
        i_to_end_mod[i] = (i_to_end_mod[i-1] + int(S[-i]) * pow(10, i-1, 2019)) % 2019
    n_i_to_j_mod[i_to_end_mod[i]] += 1

ans = n_i_to_j_mod[0] + (n_i_to_j_mod[0] * (n_i_to_j_mod[0]-1))//2
for i in range(1, 2019):
    if n_i_to_j_mod[i] >= 2:
        ans += (n_i_to_j_mod[i] * (n_i_to_j_mod[i]-1)) // 2
print(ans)