[알고리즘]-계차 누적합 계산

buckshot·2024년 5월 10일

알고리즘

목록 보기
7/19
post-thumbnail

계차와 누적합

정수 A1,A2,,ANA_1, A_2, ···, A_N 이 있을 때,

계차는 수열에서 인접한 항들 간의 차이를 나태낸다.
Bi=AiAi1B_i=A_i - A_{i-1}

누적합은 각 항의 값들을 차례로 더한 결과를 타나낸다.
Bi=A1+A2++ANB_i=A_1 + A_2 + ··· + A_N

34891423

의 계차와 누적합은 아래와 같이 된다.

314159
계차
3715243861
누적합

계차와 누적합은 서로 반대로 생각할 수 있다.
예를 들어서

34891423

의 계차는

314159

이고

314159

의 누적합은

34891423

이렇게 나타난다.

다른 예에서도 이 성질이 성립이 된다.

Ex.1

34891423

누적합/계차↑누적합 / ↓계차

314159

Ex.2

156101213

누적합/계차↑누적합 / ↓계차

141421

계차는 직접 계산을 하여도 복잡도 O(N)O(N)으로 구할 수 있다. 하지만 누적합을 직접 계산하면 B1B_1을 구하기 위해서 1번의 덧셈, B2B_2를 수하기 위하여 2번의 덧셈, ···, BNB_N을 구하기 위하여 NN번을 더해야 하므로, 합계 계산 횟수는 N(N+1)÷2N(N+1)\div 2회가 된다. 따라서 복잡도는 O(N2)O(N^2)가 된다.

이때 누접합이 계차의 반대라는 것을 사용하여 다음과 같은 순서로 계산을 한다면, 복잡도 O(N)O(N)으로 계산이 된다

B1=A1B_1=A_1
$i=1, 2, 3, ․․․, N순서이다.

A1A_1A2A_2A3A_3A4A_4A5A_5A6A_6
원래 배열314159
↓+↓+↓+↓+↓+↓+
누적합34891423
+→+→+→+→+→

예제 문제

누적합

  • 입장 인원 계산하기

    NN일 동안 진행이 되는 행사에서 ii번째 날에 AA명의 인원이 입장할 예정이다. 질문 QQ개의 답을 하시오.
    Q1.Q_1. L1L_1번째 날에서 R1R_1 날 까지의 입장객의 수는?
    Q2.Q_2. L2L_2번째 날에서 R2R_2 날 까지의 입장객의 수는?

    Q.Q. LQL_Q번째 날에서 RQR_Q 날 까지의 입장객의 수는?

    일단 이러한 문제를 해결하는 방법으로는 가장 간단하게 직접 계산을 하는 방법이 있다. 하지만 하나의 질문에 대하여 최대 NN번의 덧셈을 해야한다. 그리고 질문이 모두 QQ개 이므로 복잡도가 O(NQ)O(NQ)가 된다.

    좀 더 좋은 방법으로는 2가지 방법이 있다.

  • xx번째 날에서 yy 번째 날 까지의 누적 입장 수

  • [yy번째 날까지의 누적 입장 수] - [x1x-1번째 날까지의 누적합 수]

    [A1,A_1, A2,A_2, A3,A_3, ...,..., ANA_N]의 누적합을 [B1B_1, B2B_2, B3B_3, ...,..., B4B_4] 라고 할 때

NN 번째 질문의 답은 BRNBLN1B_{R_N}-B_{L_{N-1}}이 된다.
예를 들어 입장 수를 3,1,4,1,5,9,2,63, 1, 4, 1, 5, 9, 2, 6 라고 가정을 하자
그러면 누적 입장자 수를 나타내면

31415926
누적합348914232531

여기서 3일차에서 6일차 까지의 입장한 수를 확인을 하면
4+1+5+9=194+1+5+9=19 해당 기간 동안의 누적 입장 수는 1919가 된다.

누적합을 이용하여 계산을 하면,
6일차 동안의 누적 입장수 - 2일차 동안의 누적 입장 수 를 계산하면 된다.
234=1923-4=19

각 일차의 입장수를 계산하는 방법 보다 훨 빠르게 답을 구할 수 있다.

이렇게 된다면 복잡도는 O(N+Q)O(N+Q)로 정답을 구할 수 있다.


계차

  • 눈 시물레이션

    특정 나라에 여러 지역이 있다. 해당 나라에서 지역 명칭을 서쪽에서 동쪽 방향으로 11 ~ NN으로 지정했다.
    모든 지역에서 눈이 쌓여있지 않은 상태에서 어느날 QQ일 동안 눈이 쌓였다.
    ii번째 날에 지역 Li,...,RiL_i, ..., R_i에 눈이 XcmXcm만큼 쌓일거라 예상이 된다고 한다.
    예상대로 눈이 모두 내리고 눈이 얼마나 쌓였는지 대소 관계를 나타내야 한다. N1N-1문자의 문자열을 출력하는 프로그램을 작성하라
    ii 번째 문자는 다음을 의미한다.
    (지역 ii에 쌓인 눈) > (지역 i+1i+1에 쌓인 눈) => >
    (지역 ii에 쌓인 눈) = (지역 i+1i+1에 쌓인 눈) => =
    (지역 ii에 쌓인 눈) < (지역 i+1i+1에 쌓인 눈) => <

지역ii의 현재 적설량을 AiA_i로 나타내는 배열을 만들고 차례대로 값들을 더해서 AiA_i를 구한 뒤 비교하는 방법을 생각을 할 수 있겠지만, 각 날에 최대 NN번 덧셈을 해야하고 이를 QQ일 동안 반복을 해야한다.
이 처럼 계산을 하게 된다면 복잡도는 O(NQ)O(NQ)가 된다.

보다 좋은 방법으로 계차를 사용을 한다면

'지역 ii에 쌓인 눈' 에서 '지역 i1i-1에 쌓인 눈'을 뺀 값을 BiB_i라고 나타낸다면, 지역 ll부터 rr까지에 쌓인 눈을 xcmxcm만큼 증가 시키는 조작은

  • BiB_i의 값을 xx만큼 증가시키고, Br+1B_{r+1}의 값을 xx만큼 감소 시킨다.

눈의 양 [A1,A2,...,AN][A_1, A_2, ..., A_N]과 계차[B1,B2,...,BN][B_1,B_2, ..., B_N]으로 나타낼 수 있다.

날짜/지역123456계차 ➡️123456
0000000000000
1-지역 2~5에 4cm04444004000-4
2-지역 1~6에 3cm37777334000-4
3-지역 5~6에 2cm37779534002-4
4-지역 3~6에 6cm371313151134602-4

추가적으로 "지역ii에 쌓인 눈"과 "지역i+1i+1에 쌓인 눈"의 대소 관계는 Bi+1>0B_{i+1}>0인지 판정을 할 수 있다. 따라서 계차 BiB_i를 배열로 만들어두고 물음에 맞게 계산하는 프로그램을 구성하면 해당 문제를 복잡도 O(N+Q)O(N+Q)로 답을 구할 수 있다.

profile
let's go insane

0개의 댓글