티스토리 뷰

반응형

✏️ 문제 링크

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

 

18436번: 수열과 쿼리 37

길이가 N인 수열 A1, A2, ..., AN이 있다. 이때, 다음 쿼리를 수행하는 프로그램을 작성하시오. 1 i x: Ai를 x로 바꾼다. 2 l r: l ≤ i ≤ r에 속하는 모든 Ai중에서 짝수의 개수를 출력한다. 3 l r: l ≤ i ≤ r

www.acmicpc.net

 

 

✏️ 문제 설명

 

 

✏️ 문제 풀이

기본적인 세그먼트 트리 구현 문제이긴 하나 짝수와 홀수의 개수를 처리해야 하는 문제입니다.

arr을 입력받을 때 그냥 수로 입력받는 것이 아니라 짝수일 때는 1로, 홀수일 때는 0으로 입력받게 처리하였습니다.

그 후 쿼리를 진행하였고 구간의 짝수 개수는 구간 합 방식으로, 홀수 개수는 주어진 구간의 길이에서 짝수의 개수를

빼서 진행하였습니다. 

 

✏️ 문제 코드

#include<iostream>
#include<vector>
using namespace std;
#define MAX 1000001

int N, M;
vector<long>tree, arr;
int initTree(int start, int end, int node);
void update(int start, int end, int node, int index, long value);
int findEvenSum(int start, int end, int node, int l, int r);
int main() {

	ios::sync_with_stdio(false);
	cin.tie(NULL);
	cout.tie(NULL);
	cin >> N;

	arr.resize(N);
	tree.resize(MAX * 4);
	for (int i = 0; i < N; i++) {
		cin >> arr[i];
		if (arr[i] % 2 == 0)
			arr[i] = 1;
		else
			arr[i] = 0;
	}
	initTree(0, N - 1, 1);
	int query, index;
	long l, r, value;
	cin >> M;

	for (int i = 0; i < M; i++) {
		cin >> query;
		if (query == 1) {
			cin >> index >> value;
			int d = arr[index - 1];
			if (value % 2 == 0)
				arr[index - 1] = 1;
			else
				arr[index - 1] = 0;
			long diff = arr[index - 1] - d;
			update(0, N - 1, 1, index - 1, diff);
		}
		else if (query == 2) {
			cin >> l >> r;
			cout << findEvenSum(0, N - 1, 1, l - 1, r - 1) << '\n';
		}
		else {
			cin >> l >> r;
			int len = r - l + 1;
			cout << len - findEvenSum(0, N - 1, 1, l - 1, r - 1) << '\n';
		}
	}
}

int initTree(int start, int end, int node)
{
	if (start == end)
		return tree[node] = arr[start];
	int mid = (start + end) / 2;
	return tree[node] = initTree(start, mid, node * 2) + initTree(mid + 1, end, node * 2 + 1);
}

void update(int start, int end, int node, int index, long value)
{
	if (index<start || index>end)
		return;
	tree[node] += value;
	if (start!=end) {
		int mid = (start + end) / 2;
		update(start, mid, node * 2, index, value);
		update(mid + 1, end, node * 2 + 1, index, value);
	}
}

int findEvenSum(int start, int end, int node, int l, int r)
{
	if (l > end || r < start)
		return 0;
	if (l <= start && end <= r)
		return tree[node];
	int mid = (start + end) / 2;
	return findEvenSum(start, mid, node * 2, l, r) + findEvenSum(mid + 1, end, node * 2 + 1, l, r);
}

 

 

✏️ 다른 세그먼트 트리 문제 구경하러 가기

https://pooreumjung.tistory.com/313

 

[C/C++] 백준 - 수열과 쿼리 문제

백준 14438번 수열과 쿼리 17 https://www.acmicpc.net/problem/14438 14438번: 수열과 쿼리 17 길이가 N인 수열 A1, A2, ..., AN이 주어진다. 이때, 다음 쿼리를 수행하는 프로그램을 작성하시오. 1 i v : Ai를 v로 바꾼

pooreumjung.tistory.com

https://pooreumjung.tistory.com/312

 

[C/C++] 백준 - 세그먼트 트리 문제

✏️ 세그먼트 트리 기본 개념 https://pooreumjung.tistory.com/305 Algorithm 공부 #21 - 세그먼트 트리 Algorithm 공부 #21 - 세그먼트 트리 세그먼트 트리(Segmant Tree) ● 주어진 제이터의 구간 합과 데이트 업데

pooreumjung.tistory.com

 

반응형
반응형
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/07   »
1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30 31
글 보관함