Lyw_Cyq_01
2024-11-17 09:03:57
有
若
若
现在求对于所有的
这个题的思路其实是比较显然的,可以维护前缀最大值和后缀最小值来计算答案。具体实现如下:
定义 LLONG_MIN
)。
定义 LLONG_MAX
)
那么这样维护有什么好处呢?那么显然,通过维护这些值,不需要担心时序问题,即
所以应该如何跳呢?定义
若
反之,即
最后,为了使答案最优,我们从右往左遍历,防止答案错误。
时间复杂度
code :
#include <bits/stdc++.h>
#define ll long long
#define db double
using namespace std;
ll a[1000005], pre[1000005], suf[1000005], ans[1000005];
char buf[1 << 21], *p1 = buf, *p2 = buf;
const ll getc() {
return p1 == p2 && ( p2 = (p1 = buf) + fread(buf, 1, 1 << 21, stdin), p1 == p2) ? EOF : *p1 ++;
}
const ll read() {
ll x = 0, f = 1;
char ch = getc();
while (ch < '0' || ch > '9') {
if (ch == '-') f = -1; ch = getc();
}
while (ch >= '0' && ch <= '9') {
x = (x << 1) + (x << 3) + (ch ^ 48), ch = getc();
}
return x * f;
}
const void write(ll x) {
ll sta[35], top = 0;
do {
sta[top++] = x % 10, x /= 10;
} while (x);
while (top) putchar(sta[--top] + 48);
}
int main() {
ll T = read();
while (T--) {
ll n = read();
for (ll i = 1; i <= n; i++) {
a[i] = read();
}
pre[0] = LLONG_MIN;
for (ll i = 1; i <= n; i++) {
pre[i] = max(a[i], pre[i - 1]);
}
suf[n + 1] = LLONG_MAX;
for (ll i = n; i; i--) {
suf[i] = min(a[i], suf[i + 1]);
}
for (ll i = n; i; i--) {
if (pre[i] > suf[i + 1]) {
ans[i] = ans[i + 1];
} else {
ans[i] = pre[i];
}
}
for (ll i = 1; i <= n; i++) {
write(ans[i]), putchar(' ');
}
puts("");
}
return 0;
}
AC record