공부공간

BOJ -2268 ) 수들의 합 본문

알고리즘/SegmentTree

BOJ -2268 ) 수들의 합

개발자가될수있을까? 2020. 5. 17. 21:48

 

 


https://www.acmicpc.net/problem/2268

 

2268번: 수들의 합

첫째 줄에는 N(1≤N≤1,000,000), M(1≤M≤1,000,000)이 주어진다. M은 수행한 명령의 개수이며 다음 M개의 줄에는 수행한 순서대로 함수의 목록이 주어진다. 첫 번째 숫자는 어느 함수를 사용했는지를 ��

www.acmicpc.net

 


세그먼트트리의 기본꼴인 연속합을 구하는 문제이다.

 

세그먼트트리는 O(NM)의 시간복잡도를 O(LogN)으로 줄여주는 자료구조이다.

 

기본예제를 충분히 연습하고 Fenwick 트리로 넘어가야겠다.


import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.StringTokenizer;

public class 수들의합 {
	public static long number[] , seg[];
	public static void main(String[] args) throws Exception {
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		StringTokenizer st = new StringTokenizer(br.readLine());
		StringBuilder sb = new StringBuilder();
		int n = Integer.parseInt(st.nextToken());
		int m = Integer.parseInt(st.nextToken());
		int size = (int) Math.pow(2, 1+Math.ceil(Math.log10(n) / Math.log10(2)));
		number = new long[n];
		seg = new long[size];
		for(int i = 0 ; i < m ; i ++) {
			st = new StringTokenizer(br.readLine());
			int order = Integer.parseInt(st.nextToken());
			if(order ==1) {
				// modify
				int t = Integer.parseInt(st.nextToken())-1;
				int c = Integer.parseInt(st.nextToken());
				long d = c-number[t];
				number[t] = c;
				Modify(1 , 0 , n-1 , t , d);
			} else {
				//sum
				int s = Integer.parseInt(st.nextToken())-1;
				int e = Integer.parseInt(st.nextToken())-1;
				if(e < s) {int t = s; s = e ; e =t;}
				sb.append(sum(1,0,n-1,s,e)+ "\n");
			}
		}System.out.println(sb);
	}
	private static void Modify(int node, int start, int end, int tar, long diff) {
		if(tar > end || start > tar) {
			return ;
		}
		seg[node] += diff;
		 if(start != end) {
			Modify(2*node, start, (start+end)>>1, tar, diff);
			Modify(2*node+1, ((start+end)>>1)+1, end, tar, diff);
		}
	}
	private static long sum(int node, int start, int end, int left, int right) {
		if(left > end || start > right) {
			return 0;
		} else if(left <= start && end <= right){
			return seg[node];
		} else {
			return sum (2*node , start , (start+end)>>1 , left , right ) + sum( 2*node+1 , ((start+end)>>1)+1 , end , left, right);
		}
	}
}

'알고리즘 > SegmentTree' 카테고리의 다른 글

BOJ - 1306 ) 달려라 홍준  (0) 2021.07.27
BOJ - 6549 ) 히스토그램에서 가장 큰 직사각형  (0) 2020.10.28
BOJ - 10868 ) 최솟값  (0) 2020.05.16
BOJ - 2357 ) 최솟값과 최댓값  (0) 2020.05.16
BOJ - 1275 ) 커피숍2  (0) 2020.05.16
Comments