The meaning of problems
A defined length \ (N \) a sequence of integers \ (\ {a_i \} \ ) operation is: select the leftmost sequence \ (/ \) rightmost element and delete it
\ (A \) and \ (B \) rotation sequence \ (N \) is operated by the \ (A \) upper hand. When only one element of \ (x \) , the game is over. We define this game output \ (the X-\) . \ (A \) want to output as large as possible, and \ (B \) wanted to make it as small as possible
Before the game starts, \ (A \) has exactly \ (K \) chance of this series operate on their own to get a more favorable situation
When \ (A \) and \ (B \) are in accordance with the optimal strategy when playing the game, the output value of the game will be how much
For each \ (K = 0 \. 1-N to \) , calculates the answer
solution
And concrete proof that question is almost identical
The main difficulty lies in the \ (K = 0 \ to N -1 \) in each case are calculated corresponding to answers
We can find the answer for a range of value only to its center point and neighboring points about (there are different parity)
So, the answer to each sub-parity-processing center point
We observed that as the length of the extending section, the central section is set to the both sides of the expanding
This inspired us to use the information obtained prior to new statistics answer
Repeat points using the information transfer parity, the complexity can be done \ (O (N) \)
Code
(Due to the sub-sub-tasks, so the code a little bloated)
#include <cstdio>
#include <iostream>
#include <algorithm>
using namespace std;
int N, K;
int a[200100];
namespace sub1 {
int f[2010][2010][2];
int calc(int k) {
int res = 0;
for (int i = 0; i <= k; ++i)
res = max(res, f[1 + i][N - k + i][0]);
return res;
}
void solve() {
for (int i = 1; i <= N; ++i) f[i][i][0] = f[i][i][1] = a[i];
for (int i = 2; i <= N; ++i)
for (int j = 1; j + i - 1 <= N; ++j) {
int l = j, r = j + i - 1;
f[l][r][0] = max(f[l + 1][r][1], f[l][r - 1][1]),
f[l][r][1] = min(f[l + 1][r][0], f[l][r - 1][0]);
}
if (K != -1)
printf("%d\n", calc(K));
else {
for (int i = 0; i < N; ++i)
printf("%d%c", calc(i), " \n"[i == N - 1]);
}
}
}
namespace sub2 {
int f[200100], g[200100], ans[200100];
void solve() {
f[1] = a[1], f[N] = a[N];
for (int i = 2; i < N; ++i) {
int tmp = max(a[i - 1], max(a[i], a[i + 1]));
if (a[i] == tmp)
f[i] = max(a[i - 1], a[i + 1]);
else
f[i] = a[i];
}
for (int i = 1; i < N; ++i)
g[i] = max(a[i], a[i + 1]);
if (N & 1) {
int l = (N + 1) / 2, r = (N + 1) / 2, sum = f[l];
ans[0] = sum;
for (int i = 2; i < N; i += 2) {
l--, r++;
sum = max(sum, max(f[l], f[r]));
ans[i] = sum;
}
l = N / 2, r = N / 2 + 1, sum = 0;
for (int i = 1; i < N; i += 2) {
sum = max(sum, max(g[l], g[r]));
l--, r++;
ans[i] = sum;
}
} else {
int l = N / 2, r = N / 2, sum = g[l];
ans[0] = sum;
for (int i = 2; i < N; i += 2) {
l--, r++;
sum = max(sum, max(g[l], g[r]));
ans[i] = sum;
}
l = N / 2, r = N / 2 + 1, sum = 0;
for (int i = 1; i < N; i += 2) {
sum = max(sum, max(f[l], f[r]));
l--, r++;
ans[i] = sum;
}
}
ans[N - 1] = *max_element(a + 1, a + N + 1);
if (K == -1)
for (int i = 0; i < N; ++i) printf("%d%c", ans[i], " \n"[i == N - 1]);
else
printf("%d\n", ans[K]);
}
}
int main() {
// freopen("game.in", "r", stdin);
// freopen("game.out", "w", stdout);
scanf("%d%d", &N, &K);
for (int i = 1; i <= N; ++i) scanf("%d", a + i);
if (N <= 2000)
sub1::solve();
else
sub2::solve();
return 0;
}