Mod的计算问题


首先

当询问以下问题时,AtCoder根本没有帮助,因此我将总结一下该理论及其实现。

2019的倍数(AtCoder初学者竞赛164;问题D)

问题陈述
系统会为您提供字符串S,该字符串仅包含1到9之间的数字。
求出满足以下条件的整数对(i,j)(1≤i≤j≤| S |)的总数。

条件:如果将S的第i至第j个字符视为十进制整数,则此整数是2019的倍数。

约束
1≤| S |≤200000
S是仅由1到9的数字组成的字符串

理论

可以通过堆叠多层循环来进行计算,但是在AtCoder的情况下,必须进行设计,因为它超过了计算时间的上限。

对于这种计算倍数的问题(或关于基数的问题?),您可以使用一种有效利用mod计算的算法编写高效的程序。

mod基本公式

1
2
a \equiv b \pmod{ 2019 } \\
c \equiv d \pmod{ 2019 }

{a \\\\等于b \\\\ pmod {2019} \\\\\\\\
c \\\\ equiv d \\\\ pmod {2019}
} <脚本类型= \\"数学/特克斯;模式=显示\\"> {a \\\\等价b \\\\ pmod {2019} \\\\\\\\
c \\\\ equiv d \\\\ pmod {2019}
}

1
2
3
a + c \equiv b + d \pmod{ 2019 } \\
a - c \equiv b - d \pmod{ 2019 } \\
a * c \equiv b * d \pmod{ 2019 }

{a c \\\\等价b d \\\\ pmod {2019} \\\\\\\\
a --c \\\\ equiv b --d \\\\ pmod {2019} \\\\\\\\
a * c \\\\等价b * d \\\\ pmod {2019}
} <脚本类型= \\"数学/特克斯;模式=显示\\"> {a c \\\\ equiv b d \\\\ pmod {2019} \\\\\\\\
a --c \\\\ equiv b --d \\\\ pmod {2019} \\\\\\\\
a * c \\\\等价b * d \\\\ pmod {2019}
}

成立。换句话说,可以将普通的四个算术运算的乘积和公式应用于mod的计算。

顺便说一下,以下规则也适用于商。

ab \\\\等值ac <脚本类型= \\"数学/特克斯\\"> ab \\\\等价ac和<脚本类型= \\"数学/特克斯\\"> a和p <脚本类型= \\"数学if / tex \\"> p相对质数,b \\\\等效c <脚本类型= \\"数学/ tex \\"> b \\\\等效c

适用于此问题

给定字符串S <脚本类型= \\"数学/特克斯\\"> S为

1
S = s_n s_{n-1} \dots s_2 s_1

{S = s_n s_ {n-1} \\\\点s_2 s_1
} <脚本类型= \\"数学/特克斯;模式=显示\\"> {S = s_n s_ {n-1} \\\\点s_2 s_1
}

假设它是

。换句话说,问题的反面是