Skip to content

Commit 3b0a613

Browse files
Add files via upload
1 parent b6c1434 commit 3b0a613

File tree

1 file changed

+219
-0
lines changed

1 file changed

+219
-0
lines changed
Lines changed: 219 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,219 @@
1+
#include <iostream>
2+
#include <vector>
3+
#include <algorithm>
4+
using namespace std;
5+
6+
#define LEFT(n) (2*n)
7+
#define RIGHT(n) (2*n + 1)
8+
9+
struct segment
10+
{
11+
int left, right, index;
12+
13+
};
14+
15+
const int MAX_N = 1e5 + 5, oo = 1e9 + 1;
16+
vector <int> A(MAX_N, 0), zero_left(MAX_N, 0), zero_right(MAX_N, 0), first_segment_with_left(MAX_N, 0);
17+
pair <int, int> min_tree[3*MAX_N];
18+
19+
int get_zero_left(int i)
20+
{
21+
if(i == zero_left[i])
22+
{
23+
return zero_left[i];
24+
}
25+
26+
zero_left[i] = get_zero_left(zero_left[i]);
27+
return zero_left[i];
28+
}
29+
30+
int get_zero_right(int i)
31+
{
32+
if(i == zero_right[i])
33+
{
34+
return zero_right[i];
35+
}
36+
37+
zero_right[i] = get_zero_right(zero_right[i]);
38+
return zero_right[i];
39+
}
40+
41+
void calculate_earliest_segment_for_each_position(int no_of_elements, int no_of_segments, vector <pair <int, int> > &S)
42+
{
43+
for(int i = 1; i <= no_of_elements + 1; i++)
44+
{
45+
first_segment_with_left[i] = no_of_segments + 1;
46+
}
47+
48+
for(int i = no_of_segments; i >= 1; i--)
49+
{
50+
first_segment_with_left[S[i].first] = i;
51+
52+
//cout << "Segment First segment with left " << S[i].first << " = " << first_segment_with_left[S[i].first] << "\n";
53+
}
54+
55+
for(int i = no_of_elements; i >= 1; i--)
56+
{
57+
if(first_segment_with_left[i] == no_of_segments + 1)
58+
{
59+
first_segment_with_left[i] = first_segment_with_left[i + 1];
60+
}
61+
62+
//cout << "First segment with left " << i << " = " << first_segment_with_left[i] << "\n";
63+
}
64+
}
65+
66+
pair <int, int> min(pair <int, int> A, pair <int, int> B)
67+
{
68+
return (A.first < B.first ? A : B);
69+
}
70+
71+
void build(int n, int left, int right, vector <pair <int, int> > &S)
72+
{
73+
if(left == right)
74+
{
75+
int index = left;
76+
min_tree[n].first = S[index].second;
77+
min_tree[n].second = index;
78+
return;
79+
}
80+
81+
int mid = (left + right)/2;
82+
build(LEFT(n), left, mid, S);
83+
build(RIGHT(n), mid + 1, right, S);
84+
85+
min_tree[n] = min(min_tree[LEFT(n)], min_tree[RIGHT(n)]);
86+
}
87+
88+
void update(int n, int left, int right, int index, int value)
89+
{
90+
if(index < left || right < index)
91+
{
92+
return;
93+
}
94+
95+
if(left == right)
96+
{
97+
min_tree[n].first = value;
98+
return;
99+
}
100+
101+
int mid = (left + right)/2;
102+
update(LEFT(n), left, mid, index, value);
103+
update(RIGHT(n), mid + 1, right, index, value);
104+
105+
min_tree[n] = min(min_tree[LEFT(n)], min_tree[RIGHT(n)]);
106+
}
107+
108+
pair <int, int> get_minimum(int n, int left, int right, int query_left, int query_right)
109+
{
110+
if(query_right < left || right < query_left || right < left || query_right < query_left)
111+
{
112+
return make_pair(oo, 0);
113+
}
114+
115+
if(query_left <= left && right <= query_right)
116+
{
117+
return min_tree[n];
118+
}
119+
120+
int mid = (left + right)/2;
121+
pair <int, int> left_answer = get_minimum(LEFT(n), left, mid, query_left, query_right);
122+
pair <int, int> right_answer = get_minimum(RIGHT(n), mid + 1, right, query_left, query_right);
123+
124+
pair <int, int> answer = min(left_answer, right_answer);
125+
126+
return answer;
127+
}
128+
129+
void subtract(int index)
130+
{
131+
A[index]--;
132+
133+
if(A[index] == 0 && A[index - 1] == 0)
134+
{
135+
zero_left[index] = zero_left[index - 1];
136+
zero_right[index - 1] = index;
137+
}
138+
139+
if(A[index] == 0 && A[index + 1] == 0)
140+
{
141+
zero_right[index] = zero_right[index + 1];
142+
zero_left[index + 1] = index;
143+
}
144+
145+
//cout << index << " is now " << A[index] << " New left = " << get_zero_left(index) << " New right = " << get_zero_right(index) << "\n";
146+
}
147+
148+
int get_segments(int left, int right, int no_of_segments)
149+
{
150+
int count = 0;
151+
while(get_minimum(1, 1, no_of_segments, first_segment_with_left[left], no_of_segments).first <= right)
152+
{
153+
count++;
154+
155+
int index = get_minimum(1, 1, no_of_segments, first_segment_with_left[left], no_of_segments).second;
156+
157+
//cout << "L = " << left << " First segment = " << first_segment_with_left[left] << "\n";
158+
//cout << "Minimum in [" << first_segment_with_left[left] << "," << no_of_segments << "] is "
159+
//<< get_minimum(1, 1, no_of_segments, first_segment_with_left[left], no_of_segments).first << " at index " << index << "\n";
160+
update(1, 1, no_of_segments, index, oo);
161+
}
162+
163+
// cout << "Count = " << count << "\n";
164+
165+
return count;
166+
}
167+
168+
int main()
169+
{
170+
int no_of_elements, no_of_segments;
171+
cin >> no_of_elements >> no_of_segments;
172+
173+
for(int i = 1; i <= no_of_elements; i++)
174+
{
175+
cin >> A[i];
176+
}
177+
178+
zero_left[0] = 1;
179+
zero_right[no_of_elements + 1] = no_of_elements;
180+
for(int i = 1; i <= no_of_elements; i++)
181+
{
182+
zero_left[i] = zero_right[i] = i;
183+
}
184+
185+
vector <pair <int, int> > S(no_of_segments + 1);
186+
for(int i = 1; i <= no_of_segments; i++)
187+
{
188+
cin >> S[i].first >> S[i].second;
189+
}
190+
sort(S.begin(), S.end());
191+
calculate_earliest_segment_for_each_position(no_of_elements, no_of_segments, S);
192+
193+
/*for(int i = 1; i <= no_of_segments; i++)
194+
{
195+
cout << "Segment " << i << " " << S[i].first << " " << S[i].second << "\n";
196+
}*/
197+
198+
build(1, 1, no_of_segments, S);
199+
200+
int no_of_operations;
201+
cin >> no_of_operations;
202+
203+
vector <int> answer(no_of_operations + 1);
204+
for(int i = 1; i <= no_of_operations; i++)
205+
{
206+
int encrypted_index;
207+
cin >> encrypted_index;
208+
209+
int actual_index = encrypted_index + answer[i - 1];
210+
subtract(actual_index);
211+
answer[i] = answer[i - 1] + get_segments(get_zero_left(actual_index), get_zero_right(actual_index), no_of_segments);
212+
213+
//cout << "Answer = " << answer[i] << "\n";
214+
cout << answer[i] << "\n";
215+
}
216+
217+
return 0;
218+
}
219+

0 commit comments

Comments
 (0)