- Today
- Total
- ์ธํด
- MST
- ๊ตฌํ
- CS
- array
- ์๋ฐ์์ ์
- pytorch
- ๋ฐฑ์ค
- ์๋ฐ
- dp
- ์์์ ๋ ฌ
- leetcode
- ํ๋ก๊ทธ๋๋จธ์ค
- PS
- Graph
- ๋ฐ์ดํฐ๋ฒ ์ด์ค
- ๋ฌธ๋ฒ
- ๊ทธ๋ฆฌ๋
- tree
- ์กธ์ ์ํ
- BFS
- Algorithm
- ์๋ฃ๊ตฌ์กฐ
- java
- ๋ค์ต์คํธ๋ผ
- ๋ฒจ๋งํฌ๋
- database
- spring
- OOP
- ๋ฐฑ์๋
Partially Committed
์ธ๊ทธ๋จผํธ ํธ๋ฆฌ (Java, Segment tree) ๋ณธ๋ฌธ
์ธ๊ทธ๋จผํธ ํธ๋ฆฌ (Java, Segment tree)
WonderJay 2023. 8. 9. 12:32๊ธฐ์ ์ฝํ ์์ ์ธ๊ทธ๋จผํธ ํธ๋ฆฌ๋ฅผ ์๊ตฌํ๋ ๊ฒฝ์ฐ๋ ํ์น ์์ ๊ฒ ๊ฐ์ง๋ง
ํ์ํ ์ผ์ด ์๊ฒจ์
์ด์ฐธ์ ์ ๋ฆฌํด๋ณด๋ ค๊ณ ํ๋ค..
๊ฐ์ด ๋ณํ์ง ์๋ ๋ฐ์ดํฐ๊ฐ ์ฃผ์ด์ก์ ๋,
๊ตฌ๊ฐ ํฉ์ ๋น ๋ฅด๊ฒ ๊ตฌํ๋ ๋ฐฉ๋ฒ์
prefix sum ์ ์ด์ฉํ๋ฉด ๋๋ค.
๊ตฌ๊ฐ ํฉ(Prefix Sum) ์๊ณ ๋ฆฌ์ฆ
๋ชฉ์ฐจ 1. ๊ตฌ๊ฐ ํฉ(Prefix Sum)์ด๋? 2. ๊ตฌ๊ฐ ํฉ(Prefix Sum)์ด ์ด๋์ ์ฐ์ผ๊น? 3. Prefix Sum Algorithm 4. Prefix Sum์ด ์ฐ์ด๋ ๋ฌธ์ ๋ค 1. ๊ตฌ๊ฐ ํฉ(Prefix Sum)์ด๋? ๊ณต๋ถ๋ฅผ ํ๋ค๋ณด๋ฉด ๋ถ๋ถ ํฉ, ๊ตฌ๊ฐ ํฉ์ ๊ฐ๋ ์ด ํท๊ฐ๋ฆด ๋
www.crocus.co.kr
๋ง์ฝ, ๋ฐ์ดํฐ๊ฐ ๋ณํ๋ค๋ฉด Fenwick tree ๋ฅผ ๊ตฌํํด์ ๊ตฌ๊ฐ ์ฟผ๋ฆฌ๋ฅผ ํจ์จ์ ์ผ๋ก ํด๊ฒฐํ ์ ์๊ฒ ๋ค.
https://yabmoons.tistory.com/438
[ ํ์ ํธ๋ฆฌ(FenwickTree) ] ๊ฐ๋ ๊ณผ ๊ตฌํ๋ฐฉ๋ฒ (C++)
์ด๋ฒ ๊ธ์์๋ ํ์ ํธ๋ฆฌ(FenwickTree) ์ ๋ํด์ ์ด์ผ๊ธฐํด๋ณด์. ์ด ๊ธ์ ์ฝ๊ธฐ ์ ์ ๋จผ์ '์ธ๊ทธ๋จผํธ ํธ๋ฆฌ'์ ๋ํ ๊ธ์ ์ฝ๊ณ ์ค๋ ๊ฒ์ ๊ถ์ฅํ๋ค.์ธ๊ทธ๋จผํธ ํธ๋ฆฌ๋ฅผ ๋ชจ๋ฅธ๋ค๊ณ ํด์ ํ์ ํธ๋ฆฌ๋ฅผ ์ ๋ ์ด
yabmoons.tistory.com
ํ์ง๋ง ๊ตฌ๊ฐ์ ๋ํ ํน์ ๊ฐ์ ๊ตฌํ๋ ๊ฒฝ์ฐ๋ ํ์ ํธ๋ฆฌ๋ฅผ ์ด์ฉํด์ ํจ์จ์ ์ผ๋ก ํด๊ฒฐํ๊ธฐ ์ด๋ ต๋ค.
์๋ฅผ ๋ค์ด ๊ตฌ๊ฐ [A, B] ์์์ ์ต๋๊ฐ, ์ต์๊ฐ, gcd, lcm, ๋ฑ๋ฑ
์ด๋ฅผ ํด๊ฒฐํ๊ธฐ ์ํด์๋ ์ธ๊ทธ๋จผํธ ํธ๋ฆฌ๋ฅผ ํ์ฉํ๋ ๊ฒ์ด ์ ๋ฆฌํ๋ค. (ํ์ ํธ๋ฆฌ๋ณด๋ค ์๊ตฌํ๋ ๋ฉ๋ชจ๋ฆฌ๊ฐ ๋ ๋ง๊ธด ํจ)
๊ตฌ๊ฐ ์ฟผ๋ฆฌ๊ฐ ์ฃผ์ด์ก์ ๋,
์ธ๊ทธ๋จผํธ ํธ๋ฆฌ๋ฅผ ์ด์ฉํ๋ฉด
์ฟผ๋ฆฌ ์ฐ์ฐ๊ณผ ์ ๋ฐ์ดํธ ์ฐ์ฐ์ log(N) ์ ํด๊ฒฐํ ์ ์๋ค.
โ ๏ธ ํ์ง๋ง Range update ์ ๋ํด์๋ ๋นํจ์จ์ ์ด๋ค. M ๊ฐ์ ๋ฐ์ดํฐ๊ฐ ์๋ ๊ตฌ๊ฐ์ ์ผ๊ด์ ์ผ๋ก ์ ๋ฐ์ดํธ๋ฅผ ์ํํ๋ค๊ณ ํ๋ฉด ๊ธฐ์กด์ ์ธ๊ทธ๋จผํธ ํธ๋ฆฌ์์๋ M*log(N) ์ด ํ์ํ๋ค. Range update ๊ฐ ๋ง์ด ๋ฐ์ํ์ง ์๋๋ค๋ฉด ํฐ ๋ฌธ์ ๊ฐ ์๊ฒ ์ง๋ง, ๋ง์ฝ Range update ๊ฐ ์์ฃผ ๋ฐ์ํ๋ ํ๊ฒฝ์ด๋ผ๋ฉด Lazy propagation ์ด๋ผ๋ ๊ธฐ๋ฒ์ ์ฌ์ฉํด์ผ ํจ์จ์ ์ผ๋ก ํด๊ฒฐํ ์ ์๋ค. ๋ณธ ํฌ์คํ ์์๋ ๊ทธ ๊ฒฝ์ฐ๊น์ง๋ ๊ณ ๋ คํ์ง ์๋๋ค.
์ค๋ช ์ ์๋์ ์ฃผ์์ผ๋ก ๋์ฒดํ๋๋ก ํ๊ฒ ๋ค.
public static class segmentTree {
long[] tree; // ํธ๋ฆฌ์ ๋
ธ๋ ๊ฐ์ด ์ ์ฅ๋ ๋ฐฐ์ด
int N; // ์๋ณธ ๋ฐ์ดํฐ์ ๊ฐ์
public segmentTree(int n, int[] arr) { // ์์ฑ์
N = n;
tree = new long[n * 4]; // ํธ๋ฆฌ์ ๋
ธ๋๋ 2N <= x <4N ์ด ๋ณด์ฅ๋๋ค. (top-down)
build(arr, 1, 0, n - 1); // init
}
private long build(int[] arr, int node, int nodeLeft, int nodeRight) {
if (nodeLeft == nodeRight) { // leaf ์ ๋๋ฌํ ๊ฒฝ์ฐ์ ๊ฐ์ ๋ฃ๋๋ค.
return tree[node] = arr[nodeLeft];
}
int mid = nodeLeft + (nodeRight - nodeLeft) / 2; // overflow ๋ฐฉ์ง
// (a+b)/2 ๋ผ๊ณ ํ๋ฉด (a+b) ์์ Long overflow ๊ฐ ๋ฐ์ํ ์ ์๋ค.
long leftVal = build(arr, node * 2, nodeLeft, mid);
long rightVal = build(arr, node * 2 + 1, mid + 1, nodeRight);
return tree[node] = merge(leftVal, rightVal);
}
public long merge(long left, long right) {
return left + right; // sum
// return Math.min(left, right); // min
// return Math.max(left, right); // max
}
public Long query(int left, int right) {
// ์ค์ ์
๋ ฅ ๋ฐฐ์ด์์ [left, right] ๊ตฌ๊ฐ์์์ query ๊ฒฐ๊ณผ๊ฐ ๋ฐํ
return queryRecursive(left, right, 1, 0, N - 1);
}
public Long update(int index, int newValue) {
return updateRecursive(index, newValue, 1, 0, N - 1); // ์ฌ๊ท์ ์ผ๋ก ์
๋ฐ์ดํธ
}
public Long updateRange(int left, int right, int newValue) { // range update
return updateRangeRecursive(left, right, newValue, 1, 0, N - 1);
}
private Long queryRecursive(int left, int right, int node, int nodeLeft, int nodeRight) {
if (right < nodeLeft || nodeRight < left) {
return 0L; // ํด๋น ๋
ธ๋ ๋ฏธํฌํจ
}
if (left <= nodeLeft && nodeRight <= right) {
return tree[node]; // ํด๋น ๋
ธ๋ ํฌํจ
}
int mid = nodeLeft + (nodeRight - nodeLeft) / 2;
return merge(queryRecursive(left, right, node * 2, nodeLeft, mid),
queryRecursive(left, right, node * 2 + 1, mid + 1, nodeRight));
}
private Long updateRecursive(int index, int newValue, int node, int nodeLeft, int nodeRight) {
if (index < nodeLeft || nodeRight < index) {
return tree[node];
}
if (nodeLeft == nodeRight) { // ๋ฆฌํ ๋
ธ๋์ ๋๋ฌํ๋ฉด
return tree[node] = newValue;
}
int mid = nodeLeft + (nodeRight - nodeLeft) / 2;
Long leftVal = updateRecursive(index, newValue, node * 2, nodeLeft, mid);
Long rightVal = updateRecursive(index, newValue, node * 2 + 1, mid + 1, nodeRight);
return tree[node] = merge(leftVal, rightVal);
}
private Long updateRangeRecursive(int left, int right, int newValue, int node, int nodeLeft, int nodeRight) {
if (right < nodeLeft || nodeRight < left) {
return tree[node];
}
if (nodeLeft == nodeRight) {
return tree[node] = newValue;
}
int mid = nodeLeft + (nodeRight - nodeLeft) / 2;
Long leftVal = updateRangeRecursive(left, right, newValue, node * 2, nodeLeft, mid);
Long rightVal = updateRangeRecursive(left, right, newValue, node * 2 + 1, mid + 1, nodeRight);
return tree[node] = merge(leftVal, rightVal);
}
}
์ด์ ๋ฌธ์ ๋ฅผ ํ์ด๋ณด์.
์ ์ฝ๋๋ง ์์งํ๋ฉด ๊ฐ๋จํ๊ฒ ํด๊ฒฐํ ์ ์๋ค!
https://www.acmicpc.net/problem/1275
1275๋ฒ: ์ปคํผ์2
์ฒซ์งธ ์ค์ ์์ ๊ฐ์ N๊ณผ ํด์ ๊ฐ์ Q๊ฐ ์ฃผ์ด์ง๋ค.(1 ≤ N, Q ≤ 100,000) ๋์งธ ์ค์๋ ์ฒ์ ๋ฐฐ์ด์ ๋ค์ด๊ฐ ์๋ ์ ์ N๊ฐ๊ฐ ์ฃผ์ด์ง๋ค. ์ธ ๋ฒ์งธ ์ค์์ Q+2๋ฒ์งธ ์ค๊น์ง๋ x y a b์ ํ์์ผ๋ก x~y๊น์ง์ ํฉ
www.acmicpc.net
์ธ๊ทธ๋จผํธ ํธ๋ฆฌ๋ ์๋ฃ๊ตฌ์กฐ ์์ฒด๊ฐ ์กฐ๊ธ ๋์ด๋๊ฐ ์๊ธฐ ๋๋ฌธ์ ๊ธฐ๋ณธ ๋ฌธ์ ์ผ์ง๋ผ๋ ๊ณจ๋ I ์์ ์์ํ๋ค.
( ๋ฐฑ์ค ํฐ์ด ์ฌ๋ฆฌ๊ธฐ์ ์ข์ ,,,)
์ฌํผ ์ ๋ฌธ์ ๋ฅผ ์ฝ์ด๋ณด๋ฉด,
N ๊ฐ์ ์๋ณธ ๋ฐ์ดํฐ๊ฐ ์ฃผ์ด์ง๊ณ Q ๊ฐ์ ์ฟผ๋ฆฌ๊ฐ ์ํ๋๋ค.
๊ฐ๊ฐ์ ์ฟผ๋ฆฌ๋ sum query ๋ฅผ ์ํํ ๋ค update ๋ฅผ ์ ์ฉํ๋ ๊ฒ์ผ๋ก ์ ์๋๋ค.
์์ ๊ฐ์ด ์ ๋ ฅ์ด ์ฃผ์ด์ง๋ฉด, ๋ฐ์ดํฐ์ ๊ฐ์๋ 5๊ฐ ์ด๊ณ ์ฟผ๋ฆฌ์ ๊ฐ์๋ 2๊ฐ ์ธ ๊ฒ.
๋ฐ์ดํฐ๋ [1, 2, 3, 4, 5] ์ด๊ณ
์ฟผ๋ฆฌ 1. ์์๋ 2~3 ๊น์ง์ ํฉ์ ๊ตฌํ๊ณ , 3 ๋ฒ์จฐ์ ๊ฐ์ 1 ์ผ๋ก ๋ณ๊ฒฝํ๋ค.
์ฟผ๋ฆฌ 2. ์์๋ 3~5 ๊น์ง์ ํฉ์ ๊ตฌํ๊ณ , 4 ๋ฒ์งธ์ ๊ฐ์ 1 ์ผ๋ก ๋ณ๊ฒฝํ๋ค.
์ฃผ์ํ ์ ์, ์ ์ถ๋ ฅ์์ ์ฃผ์ด์ง๋ ์์ ๊ฐ๋ค์ ์ ๋ถ 1-indexed ์ด๊ณ
์ฐ๋ฆฌ๊ฐ ๊ตฌํํ ์๋ฃ๊ตฌ์กฐ๋ 0-indexed ๋ผ๋ ๊ฒ์ด๋ค.
๋ํ ๊ตฌ๊ฐ ์ฟผ๋ฆฌ๋ฅผ ์ํํ ๋, left ์ right ๊ฐ ์ฃผ์ด์ง๋ฉด left ๊ฐ right ๋ณด๋ค ํฌ๊ฒ ์ฃผ์ด์ง๋ ๊ฒฝ์ฐ์๋ left ์ right ๋ฅผ ๋ฐ๊พธ์ด์ฃผ์ด์ผ ํ๋ค.
์์์ ๊ตฌํํ segmentTree ํด๋์ค๋ฅผ ์ด์ฉํ๋ฉด ๋งค์ฐ ์ฝ๊ฒ ํด๊ฒฐํ ์ ์๋ค.
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
StringTokenizer stk;
// ๋ฐฑ์ค 1275 ์ปคํผ์ 2 ์๋ฃจ์
stk = new StringTokenizer(br.readLine());
int N = Integer.parseInt(stk.nextToken()); // ์์ ๊ฐ์
int Q = Integer.parseInt(stk.nextToken()); // ํด์ ๊ฐ์
int[] arr = new int[N];
stk = new StringTokenizer(br.readLine());
for (int i = 0; i < N; i++) {
arr[i] = Integer.parseInt(stk.nextToken());
}
segmentTree segmentTree = new segmentTree(N, arr);
for (int i = 0; i < Q; i++) {
stk = new StringTokenizer(br.readLine());
int x = Integer.parseInt(stk.nextToken());
int y = Integer.parseInt(stk.nextToken());
if (x > y) {
int t = x;
x = y;
y = t;
}
int a = Integer.parseInt(stk.nextToken());
int b = Integer.parseInt(stk.nextToken());
Long sum = segmentTree.query(x - 1, y - 1);
segmentTree.update(a - 1, b);
bw.write(sum + "\n");
}
bw.flush();
bw.close();
}
์ฐธ๊ณ ์๋ฃ๋ค
์ธ๊ทธ๋จผํธ ํธ๋ฆฌ(Segment Tree)
์ธ๊ทธ๋จผํธ ํธ๋ฆฌ(Segment Tree)๋ ์์ฒญํ๋ ์ฟผ๋ฆฌ์ ๋ํด ๋ฐฉ์์ด ๋ฌ๋ผ์ง ์ ์์ผ๋, ๋ชจ๋ ์ฟผ๋ฆฌ๋ฅผ ๋ค๋ฃฐ ์ ์๊ธฐ์ ๊ตฌ๊ฐ ํฉ์ ๋ํ ์ธ๊ทธ๋จผํธ ํธ๋ฆฌ๋ฅผ ์ ๋ฆฌํด ๋์์ต๋๋ค. ๋ด์ฉ์ด ๊ธธ์ง๋ง ๊ทธ๋งํผ ์์ธํ ์ค
www.crocus.co.kr
https://www.youtube.com/watch?v=075fcq7oCC8&t=938s
'๐ฅ Algorithm || ๋ฌธ์ ํ์ด > PS' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
[๋ฐฑ์ค 19622] ํ์์ค ๋ฐฐ์ 3 (JAVA) (0) | 2023.08.18 |
---|---|
[๋ฐฑ์ค 1931] ํ์์ค ๋ฐฐ์ (0) | 2023.07.28 |
[๋ฐฑ์ค 1213] ํฐ๋ฆฐ๋๋กฌ ๋ง๋ค๊ธฐ JAVA (๋ฌธ์์ด, ๊ทธ๋ฆฌ๋, ๊ตฌํ) (0) | 2023.06.26 |
[๋ฐฑ์ค 15681] ํธ๋ฆฌ์ ์ฟผ๋ฆฌ (ํธ๋ฆฌ DP) (2) | 2023.06.07 |
[๋ฐฑ์ค 9019] DSLR ์๋ฐ(BFS + ๊ฒฝ๋ก ์ถ์ ) (0) | 2023.06.03 |