#include "towers.h"
#include <bits/stdc++.h>
const int OO = 0;
using namespace std;
struct info {
int len[2][2];
info(int x = -1) {
len[0][0] = len[1][1] = -1e9;
len[0][1] = len[1][0] = -1e9;
if (x == 0) {
len[0][0] = 1;
}
if (x == 1) {
len[1][1] = 1;
}
}
info operator * (const info &a) const {
info res;
for (int i = 0; i < 2; i++) for (int j = 0; j < 2; j++) {
res.len[i][j] = max(max(res.len[i][j], len[i][j]), a.len[i][j]);
}
for (int i = 0; i < 2; i++) for (int j = 0; j < 2; j++) for (int k = 0; k < 2; k++) {
res.len[i][k] = max(res.len[i][k], len[i][j] + a.len[1 ^ j][k]);
}
return res;
}
void print() {
for (int i = 0; i < 2; i++) for (int j = 0; j < 2; j++) {
cout << i << " -> " << j << ": " << len[i][j] << '\n';
}
}
};
struct node {
vector<pair<int, info>> data;
node() {
data.emplace_back(0, info());
}
void add(int tim, info i) {
data.emplace_back(tim, i);
}
info& get(int tim) {
tim = max(tim, 0);
int lo = 0, hi = (int)data.size() - 1, mid;
while (lo < hi) {
mid = (lo + hi + 1) / 2;
if (data[mid].first <= tim) lo = mid;
else hi = mid - 1;
}
return data[lo].second;
}
};
struct segtree {
int n;
int tim;
vector<node> t;
segtree() {}
segtree(int sz) {
tim = 0;
n = max(2, sz);
while (n != (n & -n)) n += (n & -n);
t.resize(2 * n, node());
}
void fix(int x) {
t[x].add(tim, t[2 * x + 1].get(tim) * t[2 * x + 2].get(tim));
}
void upd(int x, int val) {
tim++;
x += n - 1;
t[x].add(tim, info(val));
while (x) {
x = (x - 1) / 2;
fix(x);
}
}
info query(int l, int r, int T) {
if (l > r) return info();
return query(l, r, T, 0, 0, n - 1);
}
info query(int l, int r, int T, int node, int nl, int nr) {
if (nr < l || r < nl) return info();
if (l <= nl && nr <= r) return t[node].get(T);
int mid = (nl + nr) / 2;
return query(l, r, T, 2 * node + 1, nl, mid) * query(l, r, T, 2 * node + 2, mid + 1, nr);
}
};
int oldn;
vector<int> oldh;
int n;
vector<int> taken_ind;
vector<int> h;
vector<pair<int, int>> w;
segtree T;
void init(int N, std::vector<int> H) {
oldn = N;
oldh = H;
h = { H[0], H[1] };
taken_ind = { 0, 1 };
for (int i = 2; i < oldn; i++) {
if (abs(h[h.size() - 2] - h.back()) + abs(h.back() - H[i]) == abs(h[h.size() - 2] - H[i]))
h.pop_back(), taken_ind.pop_back();
h.push_back(H[i]);
taken_ind.push_back(i);
}
n = h.size();
for (int i = 0; i + 1 < h.size(); i++)
w.emplace_back(abs(h[i] - h[i + 1]), i);
if (OO) {
cout << "w:\n";
for (const auto &i : w) cout << i.first << " " << i.second << '\n';
}
sort(w.rbegin(), w.rend());
T = segtree(n);
for (auto &i : w) {
if (h[i.second] < h[i.second + 1])
T.upd(i.second, 0);
else
T.upd(i.second, 1);
}
}
int bruteforce(int l, int r, int d) {
int len = r - l + 1;
int best = 0;
for (int mask = 0; mask < (1 << len); mask++) {
vector<int> val;
for (int i = l; i <= r; i++) {
if (mask & (1 << (i - l)))
val.push_back(oldh[i]);
}
if (val.size() % 2 == 0) continue;
bool good = true;
for (int i = 0; i + 1 < val.size(); i++) {
if (i % 2 == 0 && val[i] + d > val[i + 1]) good = false;
if (i % 2 == 1 && val[i] - d < val[i + 1]) good = false;
}
if (good)
best = max(best, (int)val.size() / 2 + 1);
}
return best;
}
int max_towers(int L, int R, int D) {
// find time
int lo = -1, hi = (int)w.size() - 1, mid;
while (lo < hi) {
mid = (lo + hi + 1) / 2;
if (w[mid].first >= D) lo = mid;
else hi = mid - 1;
}
int tim = lo + 1;
// fix L, R
auto it = lower_bound(taken_ind.begin(), taken_ind.end(), L);
int LL = *it;
int l = it - taken_ind.begin();
it = prev(upper_bound(taken_ind.begin(), taken_ind.end(), R));
int RR = *it;
int r = it - taken_ind.begin();
// break into cases - and also don't forget to consider the boundaries
if (R < LL) {
// nothing in between - this is a monotonic range
return 1;
}
// there's something in between: l <= r
if (OO) {
cout << "data until now:\n";
cout << "taken_ind: ";
for (const auto &i : taken_ind) cout << i << " "; cout << '\n';
cout << "l LL " << l << " " << LL << '\n';
cout << "r RR " << r << " " << RR << '\n';
cout << "tim " << tim << '\n';
}
info q = T.query(l, r - 1, tim);
if (OO) {
cout << "from query received:\n";
q.print();
}
if (L < LL) {
// consider left boundary
info boundary = info();
if (oldh[L] + D <= oldh[LL])
boundary = info(0);
else if (oldh[L] - D >= oldh[LL])
boundary = info(1);
q = boundary * q;
}
if (RR < R) {
// consider right boundary
info boundary = info();
if (oldh[RR] + D <= oldh[R])
boundary = info(0);
else if (oldh[RR] - D >= oldh[R])
boundary = info(1);
q = q * boundary;
}
return max(1, max(q.len[0][0], q.len[0][1]) / 2 + 1);
}
Compilation message
towers.cpp: In function 'void init(int, std::vector<int>)':
towers.cpp:112:24: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
112 | for (int i = 0; i + 1 < h.size(); i++)
| ~~~~~~^~~~~~~~~~
towers.cpp: In function 'int bruteforce(int, int, int)':
towers.cpp:140:25: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
140 | for (int i = 0; i + 1 < val.size(); i++) {
| ~~~~~~^~~~~~~~~~~~
towers.cpp: In function 'int max_towers(int, int, int)':
towers.cpp:177:3: warning: this 'for' clause does not guard... [-Wmisleading-indentation]
177 | for (const auto &i : taken_ind) cout << i << " "; cout << '\n';
| ^~~
towers.cpp:177:53: note: ...this statement, but the latter is misleadingly indented as if it were guarded by the 'for'
177 | for (const auto &i : taken_ind) cout << i << " "; cout << '\n';
| ^~~~
# |
Verdict |
Execution time |
Memory |
Grader output |
1 |
Correct |
274 ms |
976 KB |
Output is correct |
2 |
Correct |
794 ms |
1440 KB |
Output is correct |
3 |
Correct |
779 ms |
1352 KB |
Output is correct |
4 |
Correct |
793 ms |
1436 KB |
Output is correct |
5 |
Correct |
1101 ms |
1460 KB |
Output is correct |
6 |
Correct |
745 ms |
1432 KB |
Output is correct |
7 |
Correct |
818 ms |
1488 KB |
Output is correct |
8 |
Correct |
0 ms |
208 KB |
Output is correct |
9 |
Correct |
1 ms |
208 KB |
Output is correct |
10 |
Correct |
1 ms |
208 KB |
Output is correct |
# |
Verdict |
Execution time |
Memory |
Grader output |
1 |
Correct |
1 ms |
464 KB |
Output is correct |
2 |
Correct |
3 ms |
1104 KB |
Output is correct |
3 |
Incorrect |
3 ms |
1104 KB |
1st lines differ - on the 1st token, expected: '91', found: '56' |
4 |
Halted |
0 ms |
0 KB |
- |
# |
Verdict |
Execution time |
Memory |
Grader output |
1 |
Correct |
1 ms |
464 KB |
Output is correct |
2 |
Correct |
3 ms |
1104 KB |
Output is correct |
3 |
Incorrect |
3 ms |
1104 KB |
1st lines differ - on the 1st token, expected: '91', found: '56' |
4 |
Halted |
0 ms |
0 KB |
- |
# |
Verdict |
Execution time |
Memory |
Grader output |
1 |
Correct |
1083 ms |
56636 KB |
Output is correct |
2 |
Correct |
1223 ms |
56984 KB |
Output is correct |
3 |
Correct |
1340 ms |
57168 KB |
Output is correct |
4 |
Correct |
1645 ms |
75576 KB |
Output is correct |
5 |
Correct |
1360 ms |
76308 KB |
Output is correct |
6 |
Correct |
1657 ms |
75708 KB |
Output is correct |
7 |
Correct |
1706 ms |
76408 KB |
Output is correct |
8 |
Correct |
599 ms |
1444 KB |
Output is correct |
9 |
Correct |
753 ms |
1448 KB |
Output is correct |
10 |
Correct |
727 ms |
1516 KB |
Output is correct |
11 |
Correct |
773 ms |
1420 KB |
Output is correct |
12 |
Correct |
916 ms |
1444 KB |
Output is correct |
13 |
Correct |
723 ms |
1436 KB |
Output is correct |
14 |
Correct |
0 ms |
208 KB |
Output is correct |
15 |
Correct |
1 ms |
208 KB |
Output is correct |
16 |
Correct |
1 ms |
208 KB |
Output is correct |
17 |
Correct |
232 ms |
56828 KB |
Output is correct |
18 |
Correct |
358 ms |
75820 KB |
Output is correct |
19 |
Correct |
371 ms |
76488 KB |
Output is correct |
20 |
Correct |
12 ms |
1360 KB |
Output is correct |
21 |
Correct |
12 ms |
1360 KB |
Output is correct |
22 |
Correct |
224 ms |
56784 KB |
Output is correct |
23 |
Correct |
387 ms |
75912 KB |
Output is correct |
24 |
Correct |
397 ms |
76400 KB |
Output is correct |
25 |
Correct |
10 ms |
1444 KB |
Output is correct |
26 |
Correct |
11 ms |
1436 KB |
Output is correct |
27 |
Correct |
2 ms |
1104 KB |
Output is correct |
28 |
Correct |
3 ms |
1360 KB |
Output is correct |
29 |
Correct |
3 ms |
1360 KB |
Output is correct |
30 |
Correct |
1 ms |
208 KB |
Output is correct |
31 |
Correct |
1 ms |
224 KB |
Output is correct |
32 |
Correct |
2 ms |
1104 KB |
Output is correct |
33 |
Correct |
3 ms |
1360 KB |
Output is correct |
34 |
Correct |
3 ms |
1360 KB |
Output is correct |
35 |
Correct |
0 ms |
208 KB |
Output is correct |
36 |
Correct |
1 ms |
208 KB |
Output is correct |
# |
Verdict |
Execution time |
Memory |
Grader output |
1 |
Incorrect |
352 ms |
10624 KB |
1st lines differ - on the 1st token, expected: '7197', found: '7192' |
2 |
Halted |
0 ms |
0 KB |
- |
# |
Verdict |
Execution time |
Memory |
Grader output |
1 |
Correct |
1 ms |
464 KB |
Output is correct |
2 |
Correct |
3 ms |
1104 KB |
Output is correct |
3 |
Incorrect |
3 ms |
1104 KB |
1st lines differ - on the 1st token, expected: '91', found: '56' |
4 |
Halted |
0 ms |
0 KB |
- |
# |
Verdict |
Execution time |
Memory |
Grader output |
1 |
Correct |
274 ms |
976 KB |
Output is correct |
2 |
Correct |
794 ms |
1440 KB |
Output is correct |
3 |
Correct |
779 ms |
1352 KB |
Output is correct |
4 |
Correct |
793 ms |
1436 KB |
Output is correct |
5 |
Correct |
1101 ms |
1460 KB |
Output is correct |
6 |
Correct |
745 ms |
1432 KB |
Output is correct |
7 |
Correct |
818 ms |
1488 KB |
Output is correct |
8 |
Correct |
0 ms |
208 KB |
Output is correct |
9 |
Correct |
1 ms |
208 KB |
Output is correct |
10 |
Correct |
1 ms |
208 KB |
Output is correct |
11 |
Correct |
1 ms |
464 KB |
Output is correct |
12 |
Correct |
3 ms |
1104 KB |
Output is correct |
13 |
Incorrect |
3 ms |
1104 KB |
1st lines differ - on the 1st token, expected: '91', found: '56' |
14 |
Halted |
0 ms |
0 KB |
- |