-
๐ฒ Segment Tree 2 - ๋ ๋น ๋ฅธ update๋ฅผ ์ํ Lazy Propagation!ALicademy ๐ฉ๐ซ๐จ๐ซ/์๊ณ ๋ฆฌ์ฆ 2020. 9. 1. 19:27
์๋ณธ์ ๋งํฌ๋ฅผ ํตํด ํ์ธํ์ค ์ ์์ต๋๋ค.
Intro ๐
์ด์ ๊ธ ๋ง์ง๋ง์ ๋ง์๋๋ ธ๋ฏ์ด segment tree์์ ํน์ ๊ตฌ๊ฐ์ updateํ ๋ leaf node๋ฅผ ์ผ์ผ์ด ๋ฐฉ๋ฌธํด์ updateํ๋ฉด ์ค๋ณตํด์ ๋ฐฉ๋ฌธํ๋ ๋ ธ๋๊ฐ ์๊น๋๋ค. ์ด ๋๋ฌธ์ ์ ๋ง ๋ง์ update ์ฐ์ฐ์ ํด์ผ ํ๋ ๊ฒฝ์ฐ ์๊ฐ์ด ์ค๋ ๊ฑธ๋ฆด ์ ์์ต๋๋ค.
๊ทธ๋์ ์ค๋์ ๋ ๋น ๋ฅธ udpate๋ฅผ ์ํ ๊ธฐ๋ฒ์ธ Lazy propagation๐ด ์ ๋ํด ๋ฐฐ์ ๋ณด๊ฒ ์ต๋๋ค!
Lazy Propagation ๐ด
์ง๊ธ๋ถํฐ ์ฌ๋ฌ๋ถ์ด ๋ ธ๋๋ฅผ ์ง์ updateํ๋ ์ผ๊พผ๐ทโ๏ธ๐ท์ด๋ผ๊ณ ์๊ฐํด๋ด ์๋ค!
์ฌ๋ฌ๋ถ์ ์๋ ์์ ์ ๊ฐ์ segment tree๋ฅผ ๋์๋ค๋๋ฉด์ ๋ ธ๋๋ฅผ udpateํฉ๋๋ค.
๋ง์ฝ arr์ 0๋ฒ์งธ๋ถํฐ 2๋ฒ์งธ ์ธ๋ฑ์ค๊น์ง updateํ๋ผ๋ ์์ ์ด ๋ค์ด์ค๋ฉด ์ฌ๋ฌ๋ถ์ ๊ฐ๊ฐ์ ๊ฐ์ ์ ์ฅํ๊ณ ์๋ leaf node (์ ์์ ์์๋ 8, 9, 5๋ฒ์งธ ๋ ธ๋)๋ฅผ ๋ฐฉ๋ฌธํ ํ ๊ฐ์ ์์ ํ๊ณ ๊ทธ์ ๋ฐ๋ผ ์กฐ์ ๋ ธ๋๋ค์ ๊ฐ๋ ์์ ํด์ผ ํฉ๋๋ค.
๊ทธ๋ฐ๋ฐ ๋ง์ฝ ์ฌ๋ฌ๋ถ์ด ์ด์ฌํ ์๊ฐ ๋ค์ฌ๊ฐ๋ฉด์ ํ๋ํ๋ updateํ ๋ ธ๋๋ฅผ ํ๋ฒ๋ ์ฌ์ฉํ์ง ์์ผ๋ฉด ์ด๋จ๊น์? ์๋ง ๋น์ ์ ํํํ๊ณ ๋ฐฐ์ ๋นํ ๊ธฐ๋ถ์ด ๋ค์ง๋ ๋ชจ๋ฆ ๋๋ค.
๋ฟ๋ง ์๋๋ผ ๋น์ ์ ์ด๋ ๊ฒ ๋งํ ์ง๋ ๋ชจ๋ฆ ๋๋ค. '์ด์ ๋ถํฐ ์๋ค์ด ์งํ ์ผ! ๐ค ์์ผ๋ก๋ updateํ๋ ๊ฑฐ ๋ค ๋ฏธ๋ฃฐ๊บผ์ผ! ์ ๋ง ํ์ํ ๋๋ง updateํ๊ณ ๊ทธ๋ ์ง ์์ผ๋ฉด update ์ ํ ๊บผ๋ค ํฅ!๐ค'
๋ฐ๋ก ์ด ์๊ฐ์ผ๋ก๋ถํฐ Lazy propagation๐ด์ด ์์๋ฉ๋๋ค!
์ฌ๊ธฐ์ '์ ๋ง ํ์ํ ๋๋ง updateํ๊ณ ๊ทธ๋ ์ง ์์ผ๋ฉด udpate ์ ํ ๊ฒ์ด๋ค'๋ผ๋ ๋ง์ด ์กฐ๊ธ ์ถ์์ ์ ๋๋ค.
์ ํํ ๋ง์๋๋ฆฌ๋ฉด โจLazy propagation์ ํ์ ๋ ธ๋๋ฅผ ์ ๊ทผํด์ผ ํ ๋๊น์ง ํ์ ๋ ธ๋๋ฅผ updateํ๋ ๊ฒ์ ๋ฏธ๋ฃน๋๋ค.โจ
๋ํ Lazy propagation์ ๊ตฌํํ ๋๋ ๋ณดํต segment tree๋ฅผ ๋ํ๋ด๋ ๋ฐฐ์ด $tree[]$์ ํฌ๊ธฐ๊ฐ ๊ฐ์ ๋ฐฐ์ด $lazy[]$ ๋ฅผ ์ด์ฉํด lazy node๋ฅผ ํํํฉ๋๋ค. ์ฆ $lazy[i]$๋ ๋ ธ๋ $tree[i]$๋ฅผ ์ ๊ทผํด์ผ ํ ๋ ์ฆ๊ฐ์์ผ์ผ ํ ๊ฐ (๋ฌธ์ ์ ๋ฐ๋ผ ๋ค๋ฅผ ์ ์์ต๋๋ค) ์ ๋๋ค.
๊ทธ๋ ๋ค๋ฉด ๋ง์ฝ $lazy[i]$๊ฐ 0์ด๋ผ๋ ๊ฒ์ ๋ฌด์จ ๋ป ์ผ๊น์? ์ฌ๋ฌ๋ถ์ด ์๊ฐํ์๋ ๋๋ก ๋ ธ๋ $tree[i]$๋ ๋ฌด์ธ๊ฐ ํด์ผ ํ update๊ฐ ์๋ค๋ ์๋ฏธ์ ๋๋ค. ๐ โ๏ธ
๊ทธ๋ผ ์ง๊ธ๋ถํฐ Lazy propagation์ ์ด์ฉํ update์ query์ ๋ํด ์์๋ณด๊ฒ ์ต๋๋ค!
Update
update ํ๋ ๊ณผ์ ์ ๋ค์๊ณผ ๊ฐ์ 3๋จ๊ณ๋ก ๋๋ฉ๋๋ค.
-
Laziness๋ฅผ ์์ ์ ํ์ฌ ๋ ธ๋ ์๋ ๊ฐ์ผ๋ก ๋ง๋ค๊ธฐ. ๊ทธ๋ฆฌ๊ณ ๋์ ์์ ๋ ธ๋์ lazy ํ์ํ๊ธฐ.
-
ํ์ฌ ๋ ธ๋๊ฐ updateํด์ผ ํ ๊ตฌ๊ฐ์ ํฌํจ๋๋ฉด updateํ๊ธฐ
-
updateํ ์ ์ ๊ตฌ๊ฐ์ ์ฐพ๊ธฐ ์ํด ์์ ๋ ธ๋ ๋ฐฉ๋ฌธ
๊ด๋ จ ์ฝ๋๋ ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
Query
Query๋ฅผ ๊ตฌํ๋ ๊ณผ์ ์ ๋ค์๊ณผ ๊ฐ์ 2๋จ๊ณ๋ก ๋๋ฉ๋๋ค.
-
Laziness๋ฅผ ์์ ์ ํ์ฌ ๋ ธ๋ ์๋ ๊ฐ์ผ๋ก ๋ง๋ค๊ธฐ. ๊ทธ๋ฆฌ๊ณ ๋์ ์์ ๋ ธ๋์ lazy ํ์ํ๊ธฐ.
-
Query์์ ์๊ตฌํ ์ ์ ๊ตฌ๊ฐ ์ฐพ๊ธฐ ์ํด ์์ ๋ ธ๋ ๋ฐฉ๋ฌธ
๊ด๋ จ ์ฝ๋๋ ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
Let's do PS ๐ธ
Lazy propagation์ ๋ํด ์ ์ดํด๋์ จ๋์?
๊ทธ๋ ๋ค๋ฉด ํจ๊ป BOJ 10999๋ฒ ๊ตฌ๊ฐ ํฉ ๊ตฌํ๊ธฐ2 ๋ฅผ ํ์ด๋ด ์๋ค!
๋์์ด ํ์ํ์๋ฉด ์๋ ์ฝ๋๋ฅผ ์ฐธ๊ณ ํด์ฃผ์ธ์ ๐บ
๋๋ณด๊ธฐimport java.io.BufferedReader; import java.io.InputStreamReader; public class BOJ_10999 { public static void main(String[] args) throws Exception { BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); String[] inputs = br.readLine().split(" "); int N = Integer.parseInt(inputs[0]); int M = Integer.parseInt(inputs[1]); int K = Integer.parseInt(inputs[2]); long[] arr = new long[N]; long[] sgmt = new long[4 * N]; long[] lazy = new long[4 * N]; for(int i = 0; i < N; i++) { arr[i] = Long.parseLong(br.readLine()); } build(arr, sgmt, 0, N - 1, 1); for(int i = 0; i < M + K; i++) { inputs = br.readLine().split(" "); int a = Integer.parseInt(inputs[0]); int b = Integer.parseInt(inputs[1]); int c = Integer.parseInt(inputs[2]); long d = (inputs.length > 3) ? Integer.parseInt(inputs[3]) : 0; switch(a) { case 1 : update(sgmt, lazy, 0, N - 1, 1, b-1, c-1, d); break; case 2 : System.out.println(query(sgmt, lazy, 0, N - 1, 1, b-1, c-1)); break; } } } public static void build(long[] arr, long[] sgmt, int lo, int hi, int idx) { if(lo == hi) { sgmt[idx] = arr[lo]; return; } int mid = lo + (hi - lo) / 2; build(arr, sgmt, lo, mid, 2 * idx); build(arr, sgmt, mid + 1, hi, 2 * idx + 1); sgmt[idx] = sgmt[2 * idx] + sgmt[2 * idx + 1]; } public static void update(long[] sgmt, long[] lazy, int lo, int hi, int idx, int i, int j, long val) { if(lazy[idx] != 0) { sgmt[idx] += (hi - lo + 1) * lazy[idx]; if(lo != hi) { lazy[2 * idx] += lazy[idx]; lazy[2 * idx + 1] += lazy[idx]; } lazy[idx] = 0; } if(hi < i || j < lo) return; if(i <= lo && hi <= j) { sgmt[idx] += (hi - lo + 1) * val; if(lo != hi) { lazy[2 * idx] += val; lazy[2 * idx + 1] += val; } return; } int mid = lo + (hi - lo) / 2; update(sgmt, lazy, lo, mid, 2 * idx, i, j, val); update(sgmt, lazy, mid + 1, hi, 2 * idx + 1, i, j, val); sgmt[idx] = sgmt[2 * idx] + sgmt[2 * idx + 1]; } public static long query(long[] sgmt, long[] lazy, int lo, int hi, int idx, int i, int j) { if(hi < i || j < lo) return 0; if(lazy[idx] != 0) { sgmt[idx] += (hi - lo + 1) * lazy[idx]; if(lo != hi) { lazy[2 * idx] += lazy[idx]; lazy[2 * idx + 1] += lazy[idx]; } lazy[idx] = 0; } if(i <= lo && hi <= j) return sgmt[idx]; int mid = lo + (hi - lo) / 2; return query(sgmt, lazy, lo, mid, 2 * idx, i, j) + query(sgmt, lazy, mid + 1, hi, 2 * idx + 1, i, j); } }
Segment tree๋ถํฐ Lazy propagation๊น์ง ์ ์ดํด ๋์ จ๊ธธ ๋ฐ๋ผ๋ฉฐ ๊ธ์ ๋ง์น๊ฒ ์ต๋๋ค!
๋ค์ ๊ธ์์ ๋ง๋์~~~๐๐๐
์ฐธ๊ณ
'ALicademy ๐ฉโ๐ซ๐จโ๐ซ > ์๊ณ ๋ฆฌ์ฆ' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
์ ํด๋ฆฌ๋ ์๊ณ ๋ฆฌ์ฆ - ๋ ์์ ์ต๋๊ณต์ฝ์๋?๐คจ (0) 2021.07.04 ๐ฒ Segment Tree 1 - Segment Tree๋? (0) 2020.08.31 -