题意
传送门 POJ 2823
题解
线段树
线段树维护区间的最大值与最小值,复杂度 O ( n l o g n ) O(nlogn) O(nlogn)。
#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstring>
using namespace std;
#define inf 0x3f3f3f3f
#define maxn 1000005
#define st_size (1 << 21)
struct node
{
int mx, mn;
node() {}
node(int mx, int mn) : mx(mx), mn(mn) {}
} st[st_size];
int n, k, arr[maxn], res[2][maxn];
void init(int k, int l, int r)
{
if (r - l == 1)
{
st[k].mx = st[k].mn = arr[l];
}
else
{
int chl = (k << 1) + 1, chr = (k << 1) + 2, m = (l + r) >> 1;
init(chl, l, m);
init(chr, m, r);
st[k].mx = max(st[chl].mx, st[chr].mx), st[k].mn = min(st[chl].mn, st[chr].mn);
}
}
node query(int a, int b, int k, int l, int r)
{
if (r <= a || b <= l)
{
return node(-inf, inf);
}
else if (a <= l && r <= b)
return st[k];
else
{
int chl = (k << 1) + 1, chr = (k << 1) + 2, m = (l + r) >> 1;
node n1 = query(a, b, chl, l, m), n2 = query(a, b, chr, m, r);
return node(max(n1.mx, n2.mx), min(n1.mn, n2.mn));
}
}
int main()
{
while (~scanf("%d%d", &n, &k))
{
for (int i = 0; i < n; i++)
{
scanf("%d", arr + i);
}
init(0, 0, n);
int n2 = n - k + 1;
for (int l = 0; l < n2; l++)
{
int r = l + k;
node tmp = query(l, r, 0, 0, n);
res[0][l] = tmp.mn, res[1][l] = tmp.mx;
}
for (int i = 0; i <= 1; i++)
{
for (int j = 0; j < n2; j++)
{
printf("%d%c", res[i][j], j + 1 == n2 ? '\n' : ' ');
}
}
}
return 0;
}
单调队列
单调递增队列维护区间最小值,单调递减队列维护区间最大值,复杂度 O ( n ) O(n) O(n)。
#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstring>
using namespace std;
#define inf 0x3f3f3f3f
#define maxn 1000005
int n, k, arr[maxn], q[maxn];
int main()
{
while (~scanf("%d%d", &n, &k))
{
for (int i = 0; i < n; i++)
{
scanf("%d", arr + i);
}
int l = 0, r = -1;
for (int i = 0; i < n; i++)
{
while (l <= r && q[l] <= i - k)
++l;
while (l <= r && arr[i] < arr[q[r]])
--r;
q[++r] = i;
if (i >= k - 1)
{
printf("%d ", arr[q[l]]);
}
}
putchar('\n');
l = 0, r = -1;
for (int i = 0; i < n; i++)
{
while (l <= r && q[l] <= i - k)
++l;
while (l <= r && arr[i] > arr[q[r]])
--r;
q[++r] = i;
if (i >= k - 1)
{
printf("%d ", arr[q[l]]);
}
}
putchar('\n');
}
return 0;
}