51nod 1437 迈克步
先利用单调栈or其他方法找到一个元素g[i]作为最小值的区间,设为[L, R]。
那么长度为R-L+1的组的最大值ans=max(ans,g[i])。但是有一个问题:
比如6这个元素是长度为3的组的最大值,长度为2的最大值之前更新到为4,那么实际上长度为2的最大值是多少呢?
自然是6,因为肯定6存在于长度为2的组。
于是:求得所有元素作为最小值的组的长度后,更新每个长度的最大值。然后从长度最大的组往长度小的刷新,因为:能在长度大的做最小元素,也能在长度小的组做最小元素。
所以得到ans[]后需要一个操作刷新:
for (int i = N - 1; i >= 1; --i) ans[i] = max(ans[i], ans[i + 1]);
最后的代码:
#include <stdio.h> #include <algorithm> using namespace std; const int maxN=2e5+5; int N, M, K, T; int g[maxN], L[maxN], R[maxN]; int ans[maxN]; int main() { #ifndef ONLINE_JUDGE freopen("data.in", "r", stdin); #endif scanf("%d", &N); for (int i = 1; i <= N; ++i) scanf("%d", g + i); for (int i = 1; i <= N; ++i) L[i] = i - 1, R[i] = i + 1; for (int i = 1; i <= N; ++i) while (L[i] && g[L[i]] >= g[i]) L[i] = L[L[i]]; for (int i = N; i >= 1; --i) while (R[i] <= N && g[R[i]] >= g[i]) R[i] = R[R[i]]; for (int i = 1; i <= N; ++i) { int siz = R[i] - L[i] - 1; ans[siz] = max(ans[siz], g[i]); } for (int i = N - 1; i >= 1; --i) ans[i] = max(ans[i], ans[i + 1]); for (int i = 1; i <= N; ++i) printf("%d ", ans[i]); puts(""); return 0; }