-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathsegment-vector-opt.cpp
57 lines (52 loc) · 1.33 KB
/
segment-vector-opt.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
//Solution to problem 191e
// template <class T1>
class segment{
vector <int> Rb[4 * N], Rs[4 * N], Lb[4 * N], Ls[4 * N];
int P[4 * N], Q[4 * N];
public:
vector <ll> S[4 * N];
void build(int x, int p, int q, ll a[]) {
P[x] = p;
Q[x] = q;
for(int i = p;i <= q;++i)
S[x].push_back(a[i]);
if(p == q)
return ;
int m = (p + q) >> 1, r = x << 1, l = (x << 1) + 1, po = 0, qo = 0;
build(x << 1, p, m, a);
build((x << 1) + 1, m + 1, q, a);
///
sort(S[x].begin(), S[x].end());
for(int i = 0;i < Size(S[x]);++i) {
while(po < Size(S[r]) && S[r][po] < S[x][i])
++po;
while(qo < Size(S[l]) && S[l][qo] < S[x][i])
++qo;
Rb[x].push_back(po);
Lb[x].push_back(qo);
}
po = Size(S[r]) - 1;
qo = Size(S[l]) - 1;
for(int i = Size(S[x]) - 1;i > -1;--i) {
while(po > -1 && S[r][po] > S[x][i])
--po;
while(qo > -1 && S[l][qo] > S[x][i])
--qo;
Rs[x].push_back(po);
Ls[x].push_back(qo);
}
reverse(Rs[x].begin(), Rs[x].end());
reverse(Ls[x].begin(), Ls[x].end());
}
int find(int x, int p, int q, int a, int b) {
if(a == Size(S[x]) || b == -1 || a > b)
return 0;
if(q < P[x] || Q[x] < p)
return 0;
if(p <= P[x] && Q[x] <= q)
return b - a + 1;
int tmp = find(x << 1, p, q, Rb[x][a], Rs[x][b]);
tmp += find((x << 1) + 1, p, q, Lb[x][a], Ls[x][b]);
return tmp;
}
} T;