-
Notifications
You must be signed in to change notification settings - Fork 249
/
Copy pathSegmentTree(Add-Min-Max).cpp
114 lines (98 loc) · 2.85 KB
/
SegmentTree(Add-Min-Max).cpp
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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
/******************************************************************************
Segment Tree with addition and min/max on the interval
Based on problem 1263E from https://codeforces.com/contest/1263/problem/E
******************************************************************************/
#include <iostream>
#include <fstream>
#include <cmath>
#include <algorithm>
#include <vector>
#include <set>
#include <map>
#include <stack>
#include <queue>
#include <cstdlib>
#include <cstdio>
#include <string>
#include <cstring>
#include <cassert>
#include <utility>
#include <iomanip>
using namespace std;
const int MAXN = 1000 * 1000 + 100;
const int INF = (int) 1e9;
struct node {
int mx, mn;
int add;
};
int n;
int val[MAXN];
string s;
int pos;
node tree[4 * MAXN];
void add(int v, int L, int R, int l, int r, int val) {
if (l > r)
return;
if (L == l && R == r) {
tree[v].add += val;
} else {
int mid = L + (R - L) / 2;
add(2 * v + 1, L, mid, l, min(mid, r), val);
add(2 * v + 2, mid + 1, R, max(mid + 1, l), r, val);
tree[v].mx = max(tree[2 * v + 1].mx + tree[2 * v + 1].add, tree[2 * v + 2].mx + tree[2 * v + 2].add);
tree[v].mn = min(tree[2 * v + 1].mn + tree[2 * v + 1].add, tree[2 * v + 2].mn + tree[2 * v + 2].add);
}
}
int getMin(int v, int L, int R, int l, int r) {
if (l > r) {
return INF;
}
if (L == l && R == r) {
return tree[v].mn + tree[v].add;
}
int mid = L + (R - L) / 2;
return tree[v].add + min(getMin(2 * v + 1, L, mid, l, min(mid, r)), getMin(2 * v + 2, mid + 1, R, max(l, mid + 1), r));
}
int getMax(int v, int L, int R, int l, int r) {
if (l > r) {
return -INF;
}
if (L == l && R == r) {
return tree[v].mx + tree[v].add;
}
int mid = L + (R - L) / 2;
return tree[v].add + max(getMax(2 * v + 1, L, mid, l, min(mid, r)), getMax(2 * v + 2, mid + 1, R, max(l, mid + 1), r));
}
int main() {
//assert(freopen("input.txt","r",stdin));
//assert(freopen("output.txt","w",stdout));
scanf("%d\n", &n);
getline(cin, s);
pos = 0;
for (int i = 0; i < (int) s.length(); i++) {
if (s[i] == 'L') {
if (pos > 0) pos--;
} else if (s[i] == 'R') {
pos++;
} else {
int newVal = 0;
if (s[i] == '(') {
newVal = 1;
} else if (s[i] == ')') {
newVal = -1;
}
int delta = newVal - val[pos];
val[pos] = newVal;
add(0, 0, n - 1, pos, n - 1, delta);
}
int mn = getMin(0, 0, n - 1, 0, n - 1);
int lastVal = getMin(0, 0, n - 1, n - 1, n - 1);
if (mn < 0 || lastVal != 0) {
printf("%d ", -1);
} else {
printf("%d ", getMax(0, 0, n - 1, 0, n - 1));
}
}
cout << endl;
return 0;
}