题解 P4349 【[CERC2015]Digit Division】

2019-01-30 02:44:34


假设 $m \mid a$ 且 $m \mid b$,那么 $a, b$ 两个数字拼接起来也一定被 $m$ 整除,即一定有 $m \mid \left(a \times \lceil\log_{10}b\rceil + b\right)$。这个很好理解,就不证明了。

于是我们就可以使用类似读入优化的办法,从左到右边读边取模,每当结果为零时,就意味着这个地方左边的数字区间可以被 $m$ 整除。那么根据上面的结论,这个位置无论割还是不割,都可以。

所以最终答案就是 $2^{\text{可以割的位置个数 - 1}}$。

最后特判一下:如果右半段模出来不为零(不能被整除),那么答案应该为零。

int main() {
    int n = read(), m = read(), now = 0, cnt = 0;
    std::string s; std::cin >> s;
    rep(i, 1, n) {
        now = (now * 10 + s[i - 1] - 48) % m;
        cnt += (!now);
    }
    println(now ? 0 : qpow(2, cnt - 1));
}