G. Mike and Feet
题意
一个长度为 n n n 的数组,询问所有长度为 k k k 的区间最小值的最大值( k = 1 , 2 , … , n k = 1,2,\dots,n k=1,2,…,n)。
题解
- 可以换个角度考虑,求答案为 a i a_i ai 时,区间长度的可取范围;
- 这个可以先把数组按照值的大小排序,然后用
set
维护每个区间,一个严格小的数可以分隔较大的数的答案,然后看看每个数所在的区间长度即可; - 区间长度的可取范围是 [ 1 − l e n [ i ] ] [1-len[i]] [1−len[i]] ,那么按照 a i a_i ai 的大小从大到小不重复的赋值即可。
代码
#include <bits/stdc++.h>
#define rep(i, a, n) for (int i = a; i <= n; ++i)
#define per(i, a, n) for (int i = n; i >= a; --i)
#ifdef LOCAL
#include "Print.h"
#define de(...) W('[', #__VA_ARGS__, "] =", __VA_ARGS__)
#else
#define de(...)
#endif
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
const int maxn = 2e5 + 5;
int n;
struct node{
int x, id, len;
} a[maxn];
int solve() {
scanf("%d", &n);
rep(i, 1, n) scanf("%d", &a[i].x), a[i].id = i;
sort(a + 1, a + 1 + n, [](const node &A, const node &B) {
return A.x < B.x;
});
set<pii> st;
st.insert({
1, n});
int last = 1;
rep(i, 1, n) {
if (a[i].x > a[last].x) {
rep(j, last, i - 1) {
auto it = st.upper_bound({
a[j].id, n}); --it;
int L1 = it->first, R1 = a[j].id - 1;
int L2 = a[j].id + 1, R2 = it->second;
st.erase(it);
if (L1 <= R1) st.insert({
L1, R1});
if (L2 <= R2) st.insert({
L2, R2});
}
last = i;
}
auto it = st.upper_bound({
a[i].id, n}); --it;
a[i].len = it->second - it->first + 1;
}
vector<int> ANS(n + 5);
int now = 0;
per(i, 1, n) {
rep(j, now + 1, a[i].len) ANS[j] = a[i].x;
now = max(now, a[i].len);
}
rep(i, 1, n) printf("%d%c", ANS[i], " \n"[i == n]);
return 0;
}
int main() {
#ifdef LOCAL
freopen("in.in", "r", stdin);
freopen("out.out", "w", stdout);
#endif
int T = 1;
// scanf("%d", &T);
while (T--) solve();
return 0;
}