-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathUVa-11235.cpp
More file actions
125 lines (103 loc) · 2.85 KB
/
UVa-11235.cpp
File metadata and controls
125 lines (103 loc) · 2.85 KB
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
115
116
117
118
119
120
121
122
123
124
125
#include <iostream>
#include <cstdio>
#include <string>
#include <vector>
#include <algorithm>
#include <bits/stdc++.h> // here we have all the STL we need, including istringstream and ostringstream
#define ALL(x) x.begin(), x.end()
#define FAST std::cin.tie(0); ios::sync_with_stdio(false); std::cout.tie(0);
using namespace std;
void solve();
#define vi vector<int>
// 11235 - Frequent values
class SegmentTree
{
// the segment tree is stored like a heap array
private:
vi st, A;
// recall that vi is: typedef vector<int> vi;
int n;
int left(int p) { return p << 1; }
// same as binary heap operations
int right(int p) { return (p << 1) + 1; }
void build(int p, int L, int R)
{
// O(n)
if (L == R)
// as L == R, either one is fine
st[p] = L;
// store the index
else
{
// recursively compute the values
build(left(p), L, (L + R) / 2);
build(right(p), (L + R) / 2 + 1, R);
int p1 = st[left(p)], p2 = st[right(p)];
st[p] = (A[p1] <= A[p2]) ? p1 : p2;
}
}
int rmq(int p, int L, int R, int i, int j)
{
// O(log n)
if (i > R || j < L)
return -1; // current segment outside query range
if (L >= i && R <= j)
return st[p];
// inside query range
// compute the min position in the left and right part of the interval
int p1 = rmq(left(p), L, (L + R) / 2, i, j);
int p2 = rmq(right(p), (L + R) / 2 + 1, R, i, j);
if (p1 == -1)
return p2;
// if we try to access segment outside query
if (p2 == -1)
return p1;
// same as above
return (A[p1] <= A[p2]) ? p1 : p2;
// as in build routine
}
public:
SegmentTree(const vi &_A)
{
A = _A;
n = (int)A.size();
st.assign(4 * n, 0);
build(1, 0, n - 1);
}
// copy content for local usage
// create large enough vector of zeroes
// recursive build
int rmq(int i, int j) { return rmq(1, 0, n - 1, i, j); } // overloading
};
int main () {
int n, q;
while (scanf("%d", &n), n) {
scanf("%d\n", &q);
int arr[n];
for (int i = 0; i < n; i++) {
cin >> arr[i];
}
int occ[n];
occ[0] = 1;
for (int i = 1; i < n; i++) {
if (arr[i] == arr[i - 1]) {
occ[i] = occ[i - 1] + 1;
} else {
occ[i] = 1;
}
}
vi A(occ, occ + n);
SegmentTree st(A);
while (q--) {
int i, j;
cin >> i >> j;
i--; j--;
int ans = 0;
if (arr[i] == arr[j]) {
ans = j - i + 1;
} else {
}
cout << "\n" << ans;
}
}
}