Computer Science/Algorithms

๐Ÿซ‚ Prefix Sum

metamong 2024. 9. 6.

1D Prefix Sum

โœŠ๐Ÿป ๊ตฌ๊ฐ„ ํ•ฉ ๋ฌธ์ œ๋Š” ์—ฐ์†์ ์œผ๋กœ ๋‚˜์—ด๋œ N๊ฐœ์˜ ์ˆ˜๊ฐ€ ์žˆ์„ ๋•Œ, ํŠน์ • ๊ตฌ๊ฐ„์˜ ๋ชจ๋“  ์ˆ˜๋ฅผ ํ•ฉํ•œ ๊ฐ’์„ ๊ณ„์‚ฐํ•˜๋Š” ๋ฌธ์ œ ์œ ํ˜•์„ ๋œปํ•œ๋‹ค.

 

โœŠ๐Ÿป ์˜ˆ๋ฅผ ๋“ค๋ฉด, 5๊ฐœ์˜ ๋ฐ์ดํ„ฐ๋กœ ๊ตฌ์„ฑ๋œ ์ˆ˜์—ด {10, 20, 30, 40, 50}์ด ์žˆ๋‹ค๊ณ  ๊ฐ€์ •ํ–ˆ์„ ๋•Œ, 2๋ฒˆ์งธ ์ˆ˜๋ถ€ํ„ฐ 4๋ฒˆ์งธ ์ˆ˜๊นŒ์ง€์˜ ํ•ฉ์€ 20 + 30 + 40์ธ 90์ด ๋œ๋‹ค.

 

โœŠ๐Ÿป N๊ฐœ์˜ ์ •์ˆ˜๋กœ ๊ตฌ์„ฑ๋œ ์ˆ˜์—ด์ด ์žˆ๊ณ , M๊ฐœ์˜ query ์ •๋ณด๊ฐ€ ์ฃผ์–ด์ง„๋‹ค. ๊ฐ query๋Š” left์™€ right๋กœ ๊ตฌ์„ฑ. ๊ฐ query์— ๋Œ€ํ•˜์—ฌ [left, right] ๊ตฌ๊ฐ„์— ํฌํ•จ๋œ ๋ฐ์ดํ„ฐ๋“ค์˜ ํ•ฉ์„ ์ถœ๋ ฅํ•ด์•ผ ํ•œ๋‹ค. (์ˆ˜ํ–‰ ์‹œ๊ฐ„ ์ œํ•œ์€ O(N+M))

 

→ ์œ„ ์˜ˆ์™€ ์ ‘๋ชฉํ•˜์ž๋ฉด, 5๊ฐœ์˜ ๋ฐ์ดํ„ฐ (N=5)๋กœ ๊ตฌ์„ฑ๋œ ์ˆ˜์—ด์—์„œ ๋งค๋ฒˆ ์ƒˆ๋กœ์šด query ๊ตฌ๊ฐ„๋งˆ๋‹ค ํ•ด๋‹น ํ•ฉ์„ ๊ตฌํ•œ๋‹ค๋ฉด ์‹œ๊ฐ„ ๋ณต์žก๋„๋Š” O(N*M)

→ ์ด ๋•Œ, ์‹œ๊ฐ„์˜ ํšจ์œจ์„ฑ์„ ์œ„ํ•ด ๊ตฌ๊ฐ„ ํ•ฉ(Prefix Sum; Interval Sum) ์•„์ด๋””์–ด๋ฅผ ์‚ฌ์šฉ!

 

โ€ป ๊ตฌ๊ฐ„ ํ•ฉ = ๋ฐฐ์—ด์˜ ๋งจ ์•ž๋ถ€ํ„ฐ ํŠน์ • ์œ„์น˜๊นŒ์ง€์˜ ํ•ฉ์„ ๋ฏธ๋ฆฌ ๊ตฌํ•ด ๋†“์€ ๊ฒƒ โ€ป

→ ๋”ฐ๋ผ์„œ N๊ฐœ์˜ ์ˆ˜ ์œ„์น˜ ๊ฐ๊ฐ์— ๋Œ€ํ•˜์—ฌ ์ ‘๋‘์‚ฌ ํ•ฉ์„ ๊ณ„์‚ฐํ•˜์—ฌ P์— ์ €์žฅํ•œ ๋’ค, ๋งค M๊ฐœ์˜ ์ฟผ๋ฆฌ ์ •๋ณด๋ฅผ ํ™•์ธํ•  ๋•Œ ๊ตฌ๊ฐ„ ํ•ฉ์€ P[Right] - P[Left-1]

โœŠ๐Ÿป ์•ž์— 0์„ ๋ถ™์ด๋ฉด i๋ฒˆ์งธ๋ถ€ํ„ฐ j๋ฒˆ์งธ์˜ ๋ถ€๋ถ„ํ•ฉ์„ ๊ตฌํ•  ๋•Œ, i = 1์ผ ๋•Œ์˜ ์ฒ˜๋ฆฌ๋ฅผ ๋ณ„๋„๋กœ ํ•˜์ง€ ์•Š์•„๋„ ๋œ๋‹ค. ์œ„ ๊ทธ๋ฆผ์—์„œ pre_sum = [0, 10, 30, 60, 100, 150]์œผ๋กœ ๋งŒ๋“ค์—ˆ๋‹ค๋ฉด 1๋ฒˆ์งธ๋ถ€ํ„ฐ 3๋ฒˆ์งธ์˜ ๋ถ€๋ถ„ํ•ฉ์€ ์œ„ ๊ตฌ๊ฐ„ํ•ฉ ๊ณต์‹์— ์˜ํ•ด pre_sum[3] - pre_sum[0]์œผ๋กœ ์‰ฝ๊ฒŒ ๊ตฌํ•  ์ˆ˜ ์žˆ๋‹ค. ๋งŒ์•ฝ ์•ž์— 0์„ ๋ถ™์ด์ง€ ์•Š์•˜๋‹ค๋ฉด i๊ฐ€ 1์ผ ๋•Œ ๋ณ„๋„๋กœ ์‹์„ ์ถ”๊ฐ€๋กœ ๋งŒ๋“ค์–ด์ฃผ์–ด์•ผ ํ•œ๋‹ค.

2D Prefix Sum

โœŠ๐Ÿป1์ฐจ์›๊ณผ ๋‹ค๋ฅด๊ฒŒ 2์ฐจ์› ๋ฐฐ์—ด์—์„œ์˜ ๋ถ€๋ถ„ํ•ฉ์€ ํฌํ•จ-๋ฐฐ์ œ์˜ ์›๋ฆฌ๋ฅผ ์‚ฌ์šฉํ•ด ๋ˆ„์ ํ•ฉ์„ ๊ตฌํ•œ๋‹ค. ์•„๋ž˜ ๊ทธ๋ฆผ์„ ์ฐธ๊ณ ํ•˜์ž.

: ์œ„ ๋…ธ๋ž€์ƒ‰ ๋ถ€๋ถ„ ์‚ฌ๊ฐํ˜•(3x3) ๋‚ด์˜ 9๊ฐœ์˜ ์ˆซ์ž์˜ ํ•ฉ(๋ถ€๋ถ„ํ•ฉ)์„ ๊ตฌํ•˜๊ณ ์ž ํ•œ๋‹ค. ์ผ๋‹จ ์ „์ฒด ํŒŒ๋ž€์ƒ‰ ์‚ฌ๊ฐํ˜• (1)์— ๋“ค์–ด๊ฐ„ ๋ชจ๋“  ์ˆซ์ž์˜ ํ•ฉ์—์„œ (2) ๋นจ๊ฐ„์ƒ‰ ์‚ฌ๊ฐํ˜• ๋‚ด์˜ ๋ชจ๋“  ์ˆซ์ž์˜ ํ•ฉ์„ ๋นผ๊ณ , ์ดˆ๋ก์ƒ‰ ์‚ฌ๊ฐํ˜• (3)์— ๋“ค์–ด๊ฐ„ ๋ชจ๋“  ์ˆซ์ž์˜ ํ•ฉ๋„ ๋บ€๋‹ค. ๊ทธ ๋‹ค์Œ, (2)์™€ (3)์„ ๊ณตํ†ต์œผ๋กœ ๋บ์œผ๋ฏ€๋กœ, ๋‘ ๋ฒˆ ๋บ€ ์ฃผํ™ฉ์ƒ‰ ์‚ฌ๊ฐํ˜• (4)๋ฅผ ํ•œ ๋ฒˆ ๋”ํ•œ๋‹ค. (ํฌํ•จ - ๋ฐฐ์ œ์˜ ์›๋ฆฌ)

 

โœŠ๐Ÿปโ‘  ์ฃผ์–ด์ง„ 2์ฐจ์› ๋ฐฐ์—ด์—์„œ ๋ˆ„์ ํ•ฉ ๊ตฌํ•˜๊ธฐ

: ์ด๋ฏธ ์ฃผ์–ด์ง„ 2์ฐจ์› ๋ฐฐ์—ด์—์„œ 2์ฐจ์› ๋ˆ„์ ํ•ฉ ๋ฐฐ์—ด์„ ๊ตฌํ•  ์ˆ˜๋„ ์žˆ๊ณ , ๊ฐ row๋ฅผ ์ž…๋ ฅ ๋ฐ›๋Š” ๊ณผ์ •์—์„œ ๊ตณ์ด ์ˆซ์ž๋กœ๋งŒ ์ฃผ์–ด์ง„ 2์ฐจ์› ๋ฐฐ์—ด์„ ๋งŒ๋“ค ํ•„์š” ์—†์ด ๋„์ค‘๋„์ค‘ 2์ฐจ์› ๋ˆ„์ ํ•ฉ ๋ฐฐ์—ด์„ ๋งŒ๋“ค ์ˆ˜๋„ ์žˆ๋‹ค. 

 

โ˜… ์ด ๋•Œ, 1์ฐจ์› ๋ˆ„์ ํ•ฉ ๋ฐฐ์—ด๊ณผ ๋™์ผํ•˜๊ฒŒ 2์ฐจ์› ๋ˆ„์ ํ•ฉ ๋ฐฐ์—ด ์œ„์ชฝ / ์™ผ์ชฝ์— 0์„ ์ผ๋ ฌ๋กœ ๋งŒ๋“œ๋Š”๊ฒŒ ํŽธํ•˜๋‹ค. ์ดํ›„ ๊ณต์‹ ํ•œ ๋ฒˆ๋งŒ ์จ์„œ ํ•œ๋ฒˆ์— 2์ฐจ์› ๋ถ€๋ถ„ํ•ฉ์„ ๊ตฌํ•  ์ˆ˜ ์žˆ๋‹ค!

2D Cumsum(Prefix Sum) Array & 2D Sum of Sub-Matrix

 ex) NxM size์˜ 2D array๋ฅผ ๋งŒ๋“ ๋‹ค ๊ฐ€์ •. ๊ทธ๋Ÿฌ๋ฉด 2์ฐจ์› ๋ˆ„์ ํ•ฉ ๋ฐฐ์—ด(psum) size๋Š” (N+1)x(M+1)์ด ๋˜๊ณ , ์•„๋ž˜ ์˜ˆ์‹œ๋กœ๋Š” N=5, M=4

 

โ‘  N๊ณผ M์„ ์ž…๋ ฅ ๋ฐ›๊ณ , psum์˜ ์ฒซ๋ฒˆ์งธ ํ–‰์€ (M+1)๊ฐœ์˜ 0์œผ๋กœ ๊ตฌ์„ฑ๋œ list๋กœ ์ผ๋‹จ ์ƒ์„ฑ

N,M=map(int,input().split())
psum=[[0]*(M+1)]

 

โ‘ก 1๋ถ€ํ„ฐ Nํ–‰๊นŒ์ง€ for๋ฌธ์œผ๋กœ ๋Œ๋ฆฐ๋‹ค. ๋จผ์ € psum์— appendํ•  list๋ฅผ [0]์œผ๋กœ ์ดˆ๊ธฐํ™”ํ•œ๋‹ค. 

for i in range(1,N+1):
    psum.append([0])

 

โ‘ข ์ž…๋ ฅ ๋ฐ›์€ ํ•œ ํ–‰(row)์˜ ์•ž ๋ถ€๋ถ„์— 0์„ ๋ถ™์ธ list l ์ƒ์„ฑ

for i in range(1,N+1):
    psum.append([0])
    l=[0]+list(map(int,input().split()))

 

โ‘ฃ list l์˜ ๋‘๋ฒˆ์งธ ์›์†Œ(0 ๊ทธ ๋‹ค์Œ)๋ถ€ํ„ฐ for๋ฌธ์„ ๋Œ๋ ค (0,0)๋ถ€ํ„ฐ(2D array์˜ ์™ผ์ชฝ ๋ ์‹œ์ž‘๋ถ€๋ถ„) ํ˜„์žฌ ์›์†Œ๋ฅผ ํฌํ•จํ•œ 2์ฐจ์› ๋ฐฐ์—ด๊นŒ์ง€์˜ ๋ˆ„์ ํ•ฉ์„ psum[-1]์— ์—…๋ฐ์ดํŠธํ•œ๋‹ค.

: ์œ„ ๊ทธ๋ฆผ์„ ์˜ˆ๋กœ ๋“ค์ž๋ฉด ๊ทธ๋ฆผ ์™ผ์ชฝ ์ง์‚ฌ๊ฐํ˜•์—์„œ 2x2 ํ˜•ํƒœ์˜ ํ•˜๋Š˜์ƒ‰ ์‚ฌ๊ฐํ˜• ๋ถ€๋ถ„ํ•ฉ์„ ๊ตฌํ•˜๊ณ ์ž ํ•œ๋‹ค. 6์„ ๋„ฃ์œผ๋ ค๊ณ  ํ•  ๋•Œ (๋ณธ์ธ 6) + (์™ผ์ชฝ ๋นจ๊ฐ„์ƒ‰ ์ง์‚ฌ๊ฐํ˜•์˜ ๋ˆ„์ ํ•ฉ์ธ 5) + (์œ„ ์—ฐ๋‘์ƒ‰ ์ง์‚ฌ๊ฐํ˜•์˜ ๋ˆ„์ ํ•ฉ์ธ 8) - (๋‘ ์ง์‚ฌ๊ฐํ˜•์˜ ๊ณตํ†ต ๋ถ€๋ถ„ ๋ณด๋ผ์ƒ‰ ๋ˆ„์ ํ•ฉ 3)์œผ๋กœ 6 + 5 + 8 - 3์ด ๋˜์–ด 16์ด ๋œ๋‹ค. ์ด๋Š” ์•„๋ž˜์™€ ๊ฐ™์ด ํŒŒ์ด์ฌ ์ฝ”๋“œ๋กœ ๊ตฌํ˜„ ๊ฐ€๋Šฅ

for i in range(1,N+1):
    psum.append([0])
    l=[0]+list(map(int,input().split()))
    for x in range(1,len(l)):
        psum[-1].append(l[x]+psum[i][x-1]+psum[i-1][x]-psum[i-1][x-1])

 

โ‘ค ์ด์ œ 2D cumulative sum array(๋ˆ„์ ํ•ฉ 2์ฐจ์› ๋ฐฐ์—ด)๋ฅผ ๋งŒ๋“ค์—ˆ์œผ๋ฏ€๋กœ ์ž์œ ๋กญ๊ฒŒ 2D Sum of Sub-Matrix(๋ถ€๋ถ„ํ•ฉ 2์ฐจ์› ๋ฐฐ์—ด)์„ ๊ตฌํ•ด๋ณด์ž.

 

ex) ์™„์„ฑ๋œ 2D cumulative sum array๋ฅผ ํ™œ์šฉ, (2,2)๋ถ€ํ„ฐ (3,4)๊นŒ์ง€์˜ ๋ถ€๋ถ„ํ•ฉ ๊ตฌํ•˜๊ธฐ(x์™€ y ๋ชจ๋‘ ๋ถ™์ธ 0 ์ œ์™ธํ•œ ๋‚ด์šฉ์˜ ์™ผ์ชฝ ์œ„๋ถ€ํ„ฐ 1๋ถ€ํ„ฐ ์‹œ์ž‘ํ•œ๋‹ค ๊ฐ€์ •)

: ์œ„ ํ•˜๋Š˜์ƒ‰ ์‚ฌ๊ฐํ˜•์˜ ๋ถ€๋ถ„ํ•ฉ์„ ๊ตฌํ•˜๋Š” ๊ฒƒ์ด๋ฏ€๋กœ (3,4)๊นŒ์ง€์˜ ๋ถ€๋ถ„ํ•ฉ์ธ ์—ฐ๋‘์ƒ‰ ์‚ฌ๊ฐํ˜• ๋ˆ„์ ํ•ฉ(55) - (3,1)๊นŒ์ง€์˜ ๋ถ€๋ถ„ํ•ฉ์ธ ๋…ธ๋ž€์ƒ‰ ์‚ฌ๊ฐํ˜• ๋ˆ„์ ํ•ฉ(13) - (1,4)๊นŒ์ง€์˜ ๋ถ€๋ถ„ํ•ฉ์ธ ์ฃผํ™ฉ์ƒ‰ ์‚ฌ๊ฐํ˜• ๋ˆ„์ ํ•ฉ(17) + ๊ณตํ†ต ๋ถ€๋ถ„ ๋ˆ„์ ํ•ฉ (3) ๊ฒฐ๊ณผ (55 - 13 - 17 + 3) 28์ด ๋‚˜์˜จ๋‹ค. 28์€ ๊ณง 6 + 4 + 10 + 4 + 3 + 1 ๊ฒฐ๊ณผ์™€ ๊ฐ™์Œ์„ ์•Œ ์ˆ˜ ์žˆ๋‹ค.

 

: ์ฆ‰ code๋กœ ๋‚˜ํƒ€๋‚ด๊ธฐ ์œ„ํ•ด index๋ฅผ ์ •ํ•ด๋ณธ๋‹ค๋ฉด (x1,y1)๋ฒˆ์งธ๋ถ€ํ„ฐ (x2,y2)๋ฒˆ์งธ ๊นŒ์ง€์˜ ๋ถ€๋ถ„ํ•ฉ์„ ๊ตฌํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” ๊ณต์‹ psum[x2][y2] - psum[x2][y1-1] - psum[x1-1][y2] + psum[x1-1][y1-1]๋กœ ๊ตฌํ•  ์ˆ˜ ์žˆ๋‹ค.

for _ in range(int(input())):
    x1,y1,x2,y2=map(int,input().split())
    print(psum[x2][y2]-psum[x2][y1-1]-psum[x1-1][y2]+psum[x1-1][y1-1])

code

(1) 1D Prefix Sum

#1D Prefix Sum
n=5
data=[10,20,30,40,50]

sum_value=0
prefix_sum=[0]

for i in data:
    sum_value+=i
    prefix_sum.append(sum_value)

left=3
right=4
print(prefix_sum[right] - prefix_sum[left-1]) #70

(2) 2D Prefix Sum

: NxM ํ˜•ํƒœ์˜ 2D array๋ฅผ row๋ณ„๋กœ ์ž…๋ ฅ ๋ฐ›๊ณ , ์ž…๋ ฅ ๋ฐ›์œผ๋ฉด์„œ ๋ฐ”๋กœ prefix sum 2D Array๋ฅผ ๋งŒ๋“  ๋’ค, (x1,y1) ~ (x2,y2)๋ฒˆ์งธ ์‚ฌ์ด์˜ ๋ชจ๋“  ์›์†Œ 2D ๋ถ€๋ถ„ ๋ˆ„์ ํ•ฉ ์ถœ๋ ฅ (BOJ 2167 ๋‚ด์šฉ)

N,M=map(int,input().split())
psum=[[0]*(M+1)]
for i in range(1,N+1):
    psum.append([0])
    l=[0]+list(map(int,input().split()))
    for x in range(1,len(l)):
        psum[-1].append(l[x]+psum[i][x-1]+psum[i-1][x]-psum[i-1][x-1])

for _ in range(int(input())):
    x1,y1,x2,y2=map(int,input().split())
    print(psum[x2][y2]-psum[x2][y1-1]-psum[x1-1][y2]+psum[x1-1][y1-1])

Exercises

โ˜… <BOJ S5 2167 2์ฐจ์› ๋ฐฐ์—ด์˜ ํ•ฉ> โ˜…

: 2์ฐจ์› ๋ฐฐ์—ด ๋ˆ„์ ํ•ฉ ๋Œ€ํ‘œ ๋ฌธ์ œ

 

โ˜… <BOJ S1 11660 ๊ตฌ๊ฐ„ ํ•ฉ ๊ตฌํ•˜๊ธฐ 5> โ˜…

: 2167๊ณผ ๋™์ผ. ๋‹ค๋งŒ NxN 2์ฐจ์› ๋ฐฐ์—ด์—์„œ ๋ˆ„์ ํ•ฉ ๊ตฌํ•˜๊ธฐ. size์˜ ์ œํ•œ์ด ์ปค ์œ„ 2167๊ณผ ๋‹ค๋ฅด๊ฒŒ ๋ˆ„์ ํ•ฉ ์•Œ๊ณ ๋ฆฌ์ฆ˜์œผ๋กœ๋งŒ ํ’€์ด ๊ฐ€๋Šฅ

 

โ˜… <BOJ S3 11659 ๊ตฌ๊ฐ„ ํ•ฉ ๊ตฌํ•˜๊ธฐ 4> โ˜…

: 1์ฐจ์› ๋ฐฐ์—ด ๋ˆ„์ ํ•ฉ ๋Œ€ํ‘œ ๋ฌธ์ œ

 

โ˜… <BOJ S4 13900 ์ˆœ์„œ์Œ์˜ ๊ณฑ์˜ ํ•ฉ> โ˜…

: ์„œ๋กœ ๋‹ค๋ฅธ ๋‘ ์œ„์น˜์˜ ๋‘ ์ˆ˜๋ฅผ ์ •ํ•  ๋•Œ ์™ผ์ชฝ๋ถ€ํ„ฐ ๋ˆ„์ ํ•ฉ ๊ฐœ๋…์œผ๋กœ mulsum ๊ณฑ์˜ ํ•ฉ ์•„์ด๋””์–ด์ž„์„ ์•Œ์•„์ฐจ๋ฆฌ๋Š” ๊ฒƒ์ด ์ค‘์š”


1D prefix sum array ๊ทธ๋ฆผ ์ด์ฝ”ํ…Œ 2021 ์ฐธ๊ณ 

 

'Computer Science > Algorithms' ์นดํ…Œ๊ณ ๋ฆฌ์˜ ๋‹ค๋ฅธ ๊ธ€

๐ŸŽข Topology Sort  (3) 2024.10.11
๐Ÿฃ Fibonacci Sequence  (0) 2024.06.26
๐Ÿ“ฒ Divide&Conquer  (1) 2024.06.08
๐Ÿš€ Power by Divide and Conquer  (1) 2024.06.06
๐Ÿ›ฃ๏ธ Shortest Path in an Unweighted Graph  (0) 2024.05.23

๋Œ“๊ธ€