※ 글쓴이는 취미로 코딩을 익혀보는 사람이라 정확하지 않은 내용을 담고 있을 수 있다 ※

 

이번에 볼 문제는 백준 17407번 문제인 괄호 문자열과 쿼리이다.
문제는 아래 링크를 확인하자.

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

 

17407번: 괄호 문자열과 쿼리

괄호 문자열은 '('와 ')'로 이루어진 문자열이고, 올바른 괄호 문자열은 다음과 같이 정의된다. 빈 문자열은 올바른 괄호 문자열이다. S가 올바른 괄호 문자열일 때, (S)도 올바른 괄호 문자열이

www.acmicpc.net

(과 )를 각각 1과 -1이라 할 때, 주어진 괄호 문자열이 올바른 괄호 문자열일 필요충분조건 중 하나는 처음서부터 임의의 괄호까지의 숫자의 합이 항상 0 이상이면서 여는 괄호와 닫는 괄호의 개수가 같다는 것이다.

 

따라서, 괄호를 바꿀 때마다 구간에 prefix sum의 값을 +2 또는 -2씩 바꾸는 연산을 지원하고, 그 prefix sum한 값들의 최솟값을 항상 얻을 수 있는 세그먼트 트리(segment tree)를 이용하면 문제를 해결할 수 있다.

 

아래는 제출한 소스코드이다.

#include <iostream>
#include <string>
using namespace std;

int arr[100001];
int seg[262145];
int lazy[262145];

void propagate(int L, int R, int sI) {
	seg[sI] += lazy[sI];
	if (L < R) {
		lazy[sI * 2] += lazy[sI];
		lazy[sI * 2 + 1] += lazy[sI];
	}
	lazy[sI] = 0;
}

int init(int L, int R, int sI) {
	if (L == R) return seg[sI] = arr[L];
	return seg[sI] = min(init(L, (L + R) / 2, sI * 2), init((L + R) / 2 + 1, R, sI * 2 + 1));
}

int update(int L, int R, int qL, int qR, int qVal, int sI) {
	if (lazy[sI]) propagate(L, R, sI);
	if (R < qL || qR < L) return seg[sI];
	if (qL <= L && R <= qR) {
		lazy[sI] += qVal;
		propagate(L, R, sI);
		return seg[sI];
	}
	return seg[sI] = min(update(L, (L + R) / 2, qL, qR, qVal, sI * 2), update((L + R) / 2 + 1, R, qL, qR, qVal, sI * 2 + 1));
}

int main() {
	ios::sync_with_stdio(0);
	cin.tie(0);
	
	string s; cin >> s;
	int slen = s.length();
	s = " " + s;
	for (int i = 1; i <= slen; i++) {
		if (s[i] == '(') arr[i] = arr[i - 1] + 1;
		else arr[i] = arr[i - 1] - 1;
	}

	init(1, slen, 1);

	int cnt = arr[slen], ans = 0;
	int Q; cin >> Q;
	while (Q--) {
		int x; cin >> x;
		int qVal;
		if (s[x] == '(') {
			s[x] = ')';
			qVal = -2;
			cnt -= 2;
		}
		else {
			s[x] = '(';
			qVal = 2;
			cnt += 2;
		}
		update(1, slen, x, slen, qVal, 1);

		if (cnt == 0 && seg[1] == 0) ans++;
	}

	cout << ans;
}
728x90

'BOJ' 카테고리의 다른 글

[BOJ 1179 // C++] 마지막 요세푸스 문제  (0) 2021.10.21
[BOJ 11025 // C++] 요세푸스 문제 3  (0) 2021.10.20
[BOJ 1493 // C++] 박스 채우기  (0) 2021.10.18
[BOJ 6497 // C++] 전력난  (0) 2021.10.17
[BOJ 18116 // C++] 로봇 조립  (0) 2021.10.16

+ Recent posts