首先
当询问以下问题时,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
}
假设它是
。换句话说,问题的反面是