Post

나머지 합

나머지 합

문제

출처

문제

1
2
수 N개 A1, A2, ..., AN이 주어진다. 이때, 연속된 부분 구간의 합이 M으로 나누어 떨어지는 구간의 개수를 구하는 프로그램을 작성하시오.
즉, Ai + ... + Aj (i ≤ j) 의 합이 M으로 나누어 떨어지는 (i, j) 쌍의 개수를 구해야 한다.

입력

1
2
첫째 줄에 N과 M이 주어진다. (1 ≤ N ≤ 106, 2 ≤ M ≤ 103)
둘째 줄에 N개의 수 A1, A2, ..., AN이 주어진다. (0 ≤ Ai ≤ 109)

출력

1
첫째 줄에 연속된 부분 구간의 합이 M으로 나누어 떨어지는 구간의 개수를 출력한다.

예제 입력 1

1
2
3
4
5
6
// 입력
> 5 3
> 1 2 3 1 2

// 출력
> 7

풀이

핵심 아이디어

  • “(A+B)%C 는 ((A%C) + (B%C))%C 와 같다.” 라는 성질과 누적합을 이용한다.
  • 누적합의 배열 S가 있다고 할 때, S[i]%M == S[j]%M 이면 (S[i] - S[j])%M == 0 이다.

의사코드

1
2
3
4
5
6
7
8
9
10
11
12
13
14
1. 누적합 배열 S를 만든다.
for (i -> 1 to N) {
    S[i] = S[i-1] + A[i]
}

2. 나머지가 같은 누적합의 개수를 센다.
for (i -> 0 to N) {
    count[S[i]%M] += 1
}

3. 같은 나머지의 누적합에서 2개를 선택하는 경우의 수를 계산한다.
for (i -> 0 to M) {
    answer += count[i] * (count[i] - 1) / 2
}
This post is licensed under CC BY 4.0 by the author.