This submission is migrated from previous version of oj.uz, which used different machine for grading. This submission may have different result if resubmitted.
#include <bits/stdc++.h>
#include "towers.h"
using namespace std;
typedef pair <vector <int>, vector <int>> pvv;
const int INF = 2e9 + 5;
class Tournament {
int offset;
vector <int> tour;
public:
Tournament(vector <int> vals) {
for (offset = 1; offset < vals.size(); offset *= 2);
tour.resize(2 * offset);
for (int i = 0; i < offset; i++)
tour[i + offset] = i < vals.size() ? vals[i] : INF;
for (int i = offset - 1; i; i--)
tour[i] = min(tour[2 * i], tour[2 * i + 1]);
}
Tournament() {}
int query(int x, int lo, int hi, int from, int to) const {
if (lo >= to || hi <= from)
return INF;
if (lo >= from && hi <= to)
return tour[x];
int mid = (lo + hi) / 2;
return min(query(2 * x, lo, mid, from, to), query(2 * x + 1, mid, hi, from, to));
}
int query(int from, int to) const {
return query(1, 0, offset, from, to);
}
};
int N;
vector <int> H;
map <pair <int, int>, pvv> memo;
void init(int n, vector <int> h) {
N = n;
H = h;
}
int get_smaller(const vector <int> &v, int x) {
return lower_bound(v.begin(), v.end(), x) - v.begin();
}
const pvv& calc(int l, int r) {
pvv& ref = memo[{l, r}];
if (!ref.first.empty() && !ref.second.empty())
return ref;
int n = r - l + 1;
vector <int> h(n + 2);
vector <int> lft(n + 1), rig(n + 1);
h[0] = h[n + 1] = INF;
for (int i = 1; i <= n; i++)
h[i] = H[i + l - 1];
Tournament solver(h);
stack <int> s;
s.push(0);
for (int i = 1; i <= n; i++) {
while (h[s.top()] < h[i])
s.pop();
lft[i] = s.top();
s.push(i);
}
s = stack <int> ();
s.push(n + 1);
for (int i = n; i; i--) {
while (h[s.top()] < h[i])
s.pop();
rig[i] = s.top();
s.push(i);
}
for (int i = 1; i <= n; i++) {
int tmp = solver.query(lft[i] + 1, rig[i]);
ref.first.push_back(h[i] - tmp);
ref.second.push_back(min(h[lft[i]], h[rig[i]]) - tmp);
}
sort(ref.first.begin(), ref.first.end());
sort(ref.second.begin(), ref.second.end());
return ref;
}
int max_towers(int l, int r, int d) {
const pvv& ref = calc(l, r);
return get_smaller(ref.first, d) - get_smaller(ref.second, d);
}
Compilation message (stderr)
towers.cpp: In constructor 'Tournament::Tournament(std::vector<int>)':
towers.cpp:14:29: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
14 | for (offset = 1; offset < vals.size(); offset *= 2);
| ~~~~~~~^~~~~~~~~~~~~
towers.cpp:17:28: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
17 | tour[i + offset] = i < vals.size() ? vals[i] : INF;
| ~~^~~~~~~~~~~~~
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |