배수 찾기

시간 제한2초메모리 제한128 MB

요약
0으로 시작하지 않는 구간 a_i...a_j가 나타내는 십진수가 소수 Q의 배수가 되는 인덱스 쌍 (i,j)의 개수를 최대 길이 1e5인 의사난수 생성 수열에서 세는 문제입니다.
난이도

보통10점 중 7점

유형
수학, 해시맵, 정수론, 누적 합
정답자
아직 제출이 없습니다

문제

숫자들로 이루어진 수열 a0a1⋯aN−1a_0 a_1 \cdots a_{N-1} 과 소수 QQ 가 주어진다. ai≠0a_i \ne 0 인 모든 인덱스 쌍 i≤ji \le j 에 대해, 부분 수열 aiai+1⋯aja_i a_{i+1} \cdots a_j 는 하나의 양의 정수를 십진법으로 나타낸 것으로 볼 수 있다. 앞자리가 00 인(즉 ai=0a_i = 0 인) 부분 수열은 고려하지 않는다. 대응하는 정수가 QQ 의 배수가 되는 쌍 (i,j)(i, j) 의 개수를 세는 것이 목표이다.

입력

입력은 최대 5050 개의 데이터셋으로 이루어진다. 각 데이터셋은 공백으로 구분된 네 정수 NN, SS, WW, QQ 가 담긴 한 줄이며, 1≤N≤1051 \le N \le 10^5, 1≤S≤1091 \le S \le 10^9, 1≤W≤1091 \le W \le 10^9 이고 QQ 는 10810^8 보다 작은 소수이다. 길이 NN 의 수열 a0⋯aN−1a_0 \cdots a_{N-1} 은 아래 코드로 생성되며, 여기서 aia_i 는 a[i] 로 표기한다.

int g = S;
for(int i=0; i<N; i++) {
    a[i] = (g/7) % 10;
    if( g%2 == 0 ) { g = (g/2); }
    else           { g = (g/2) ^ W; }
}

여기서 /, %, ^ 는 각각 정수 나눗셈, 나머지, 비트 단위 배타적 논리합(XOR)이다. 이 코드는 단지 유사 난수 생성기일 뿐이며, 의도된 풀이는 수열이 어떻게 생성되는지에 의존하지 않는다.

입력의 끝은 공백으로 구분된 네 개의 00 이 담긴 줄로 표시된다.

출력

각 데이터셋에 대해 답을 한 줄에 출력한다. 답은 2302^{30} 보다 작다고 가정해도 된다.

힌트

같은 수라도 그 수를 만들어 내는 위치 쌍 (i,j)(i, j) 마다 따로 센다. 예를 들어 수열이 421421 이고 Q=7Q = 7 이면 77 의 배수는 4242 와 2121 이므로 답은 22 이다. 수열이 50525052 이고 Q=5Q = 5 이면 55 의 배수는 55, 5050, 505505, 그리고 다시 55 로 모두 44 개이다. 00 이나 0505 는 세지 않는데, 고려하는 부분 수열은 반드시 00 이 아닌 자리에서 시작해야 하며(앞자리 00 금지) 양의 정수를 나타내야 하기 때문이다. 숫자 55 는 서로 다른 두 위치에 나타나므로 두 번 센다. 참고로, 샘플 입력의 처음 네 데이터셋은 각각 수열 421421, 50525052, 9507395073, 1222112221 을 생성한다.

예제3

  1. 예제 1

    입력
    3 32 64 7
    4 35 89 5
    5 555 442 3
    5 777 465 11
    100000 666 701622763 65537
    0 0 0 0
    
    예상 출력
    2
    4
    6
    3
    68530
    
  2. 예제 2

    입력
    20 100 200 7
    0 0 0 0
    
    예상 출력
    31
    
  3. 예제 3

    입력
    30 5 5 2
    30 5 5 5
    0 0 0 0
    
    예상 출력
    60
    60