考虑二分距离。
然后来考虑 check 怎么打。
整一个 ST 表维护 的最大值,然后二分距离的时候判断距离内有无满足条件的元素即可。
注意此题的坑点在于你 Query 的时候需要注意不能把自己包含进去。
具体来说就是拆询问。
把 一个 拆成 ,然后讨论一下。
#include <bits/stdc++.h>
const int N = 2e5, L = 20;
int n, a[N + 5], b[N + 5];
struct RangeMaxQuery {
int f[N + 5][L + 5];
void initTable() {
for (int i = 1; i <= n; ++i) {
f[i][0] = a[i];
}
int lim = std::log(n) / std::log(2) + 1;
for (int j = 1; j <= lim; ++j) {
for (int i = 1; i <= n - (1 << j) + 1; ++i) {
f[i][j] = std::max(f[i][j - 1], f[i + (1 << (j - 1))][j - 1]);
}
}
}
int rangeQ(int l, int r) {
if (l > r) {
return 0;
}
int len = std::log(r - l + 1) / std::log(2);
return std::max(f[l][len], f[r - (1 << len) + 1][len]);
}
int rangeQuery(int l, int r) {
if (l >= 1 && r <= n) {
return rangeQ(l, r);
} else if (l <= 0 && r <= n) {
return std::max(rangeQ(n + l, n), rangeQ(1, r));
} else {
return std::max(rangeQ(l, n), rangeQ(1, r - n));
}
}
} rmqEr;
int calc(int x) {
int l = 1, r = n / 2, res = 0;
// std::cout << "\n{" << x << "}\n";
while (l <= r) {
// std::cout << "[" << l << " " << r << "]\n";
int mid = (l + r) / 2;
if (std::max(rmqEr.rangeQuery(x - mid, x - 1), rmqEr.rangeQuery(x + 1, x + mid)) >= b[x]) {
r = mid - 1;
res = mid;
} else {
l = mid + 1;
}
}
// std::cout << "\n(" << x << " " << res << ")\n";
if (res == 0) {
return -1;
} else {
return res;
}
}
int main() {
std::ios::sync_with_stdio(0);
std::cin.tie(0);
std::cout.tie(0);
std::cin >> n;
for (int i = 1; i <= n; ++i) {
std::cin >> a[i];
}
for (int i = 1; i <= n; ++i) {
std::cin >> b[i];
}
rmqEr.initTable();
for (int i = 1; i <= n; ++i) {
std::cout << calc(i) << ' ';
}
return 0;
}