Problem:
Score : 500 points

Problem Statement

Takahashi has a string S of length N consisting of digits from 0 through 9.

He loves the prime number P. He wants to know how many non-empty (contiguous) substrings of S - there are N \times (N + 1) / 2 of them - are divisible by P when regarded as integers written in base ten.

Here substrings starting with a 0 also count, and substrings originated from different positions in S are distinguished, even if they are equal as strings or integers.

Compute this count to help Takahashi.

Constraints

1 \leq N \leq 2 \times 10^5

S consists of digits.

|S| = N

2 \leq P \leq 10000

P is a prime number.

Input

Input is given from Standard Input in the following format:

N P
S

Output

Print the number of non-empty (contiguous) substrings of S that are divisible by P when regarded as an integer written in base ten.

Sample Input 1

4 3
3543

Sample Output 1

6

Here S = 3543. There are ten non-empty (contiguous) substrings of S:

3: divisible by 3.

35: not divisible by 3.

354: divisible by 3.

3543: divisible by 3.

5: not divisible by 3.

54: divisible by 3.

543: divisible by 3.

4: not divisible by 3.

43: not divisible by 3.

3: divisible by 3.

Six of these are divisible by 3, so print 6.

Sample Input 2

4 2
2020

Sample Output 2

10

Here S = 2020. There are ten non-empty (contiguous) substrings of S, all of which are divisible by 2, so print 10.

Note that substrings beginning with a 0 also count.

Sample Input 3

20 11
33883322005544116655

Sample Output 3

68

Solution in Java (OpenJDK 11.0.6) (judge verdict: Wrong Answer)

import java.io.PrintWriter;
import java.util.HashMap;
import java.util.Map;
import java.util.Scanner;

public class Main {
    int N, P;
    int[] data;
    int[] powerOfTen;
    int[] invPowerOfTen;

    void solve(Scanner sc, PrintWriter pw) {
        N = sc.nextInt();
        P = sc.nextInt();
        data = new int[N];
        powerOfTen = new int[N + 1];
        invPowerOfTen = new int[N + 1];
        String str = sc.next();
        for (int i = 0; i < str.length(); i++) {
            data[i] = str.charAt(i) - '0';
        }
        powerOfTen[0] = 1;
        for (int i = 1; i <= N; i++) {
            powerOfTen[i] = (powerOfTen[i - 1] * 10) % P;
        }
        invPowerOfTen[0] = 1;
        for (int i = 1; i <= N; i++) {
            invPowerOfTen[i] = power(powerOfTen[i], P - 2);
        }
        pw.println(solve(0, N));
    }

    private int power(int v, int p) {
        if (p == 0) {
            return 1;
        }
        int part = power(v, p / 2);
        int candidate = (part * part) % P;
        int multiply = (p % 2) == 0 ? 1 : v;
        return (multiply * candidate) % P;
    }

    private long solve(int left, int right) {
        if (left + 1 == right) {
            return data[left] % P == 0 ? 1 : 0;
        }


        int mid = left + (right - left) / 2;
        long partial = solve(left, mid) + solve(mid, right);
        int leftStart = mid - 1;
        int currentLeft = 0;
        Map<Integer, Integer> occurs = new HashMap<>();
        while (leftStart >= left) {
            int len = mid - leftStart;
            currentLeft = (((data[leftStart] * powerOfTen[len - 1]) % P) + currentLeft) % P;
            occurs.put(currentLeft, occurs.getOrDefault(currentLeft, 0) + 1);
            leftStart--;
        }

        long result = 0;
        int rightStart = mid;
        int currentRight = 0;
        while (rightStart < right) {
            currentRight = (data[rightStart] + currentRight * 10) % P;
            int lenRight = rightStart - mid + 1;
            int matchLeft = ((P - ((invPowerOfTen[lenRight] * currentRight) % P))) % P;
            result = (result + occurs.getOrDefault(matchLeft, 0));
            rightStart++;
        }
//        System.out.println(String.format("left:%d right:%d partial:%d result:%d", left, right, partial, result));
        return result + partial;
    }

    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        PrintWriter pw = new PrintWriter(System.out);
        new Main().solve(sc, pw);
        pw.flush();
        pw.close();
        sc.close();
    }
}