Solution -「JRKSJ R1」JFCA

cirnovsky /

考虑二分距离。

然后来考虑 check 怎么打。

整一个 ST 表维护 aa 的最大值,然后二分距离的时候判断距离内有无满足条件的元素即可。

注意此题的坑点在于你 Query 的时候需要注意不能把自己包含进去。

具体来说就是拆询问。

把 一个 [l,r][l,r] 拆成 [l,x],[x+1,r][l,x],[x+1,r],然后讨论一下。

#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;
}