利用单调队列的统计。类似的题目有PKU 3250
题目意思是要求给定数列中,一个大小固定的滑动窗口内的最值
维护一个单调队列,末端插入,弹出,首端删除即可。队首始终为最值。
需要注意的两个问题:
1. 队列的初始化
2. 队首弹出需判断
- #include <iostream>
- using namespace std;
- const int N = 1000010;
- int a[N];
- int deck1[N], deck2[N], head1, tail1, head2, tail2;
- int ans1[N], ans2[N], cnt;
- int n, m;
- inline void insert(int x)
- {
- while(head1 <= tail1 && a[x] < a[deck1[tail1]]) tail1--;
- deck1[++tail1] = x;
- while(head2 <= tail2 && a[x] > a[deck2[tail2]]) tail2--;
- deck2[++tail2] = x;
- }
- int main()
- {
- int i, j, k;
- scanf("%d%d",&n, &m);
- for(i = 1; i <= n; i++) scanf("%d",&a[i]);
- head1 = tail1 = 1;
- deck1[1] = 1;
- head2 = tail2 = 1;
- deck2[1] = 1;
- for(i = 2; i <= m; i++)
- insert(i);
- ans1[1] = a[deck1[1]];
- ans2[1] = a[deck2[1]];
- cnt = 1;
- for(; i <= n; i++)
- {
- insert(i);
- if(deck1[head1] == i - m) head1++;
- if(deck2[head2] == i - m) head2++;
- ans1[++cnt] = a[deck1[head1]];
- ans2[cnt] = a[deck2[head2]];
- }
- for(i = 1; i <= cnt; i++)
- printf("%d%c", ans1[i], i == cnt? '/n' : ' ');
- for(i = 1; i <= cnt; i++)
- printf("%d%c", ans2[i], i == cnt? '/n' : ' ');
- scanf("%d",&n);
- return 0;
- }