POJ 2823 Sliding Window(单调队列)

题目链接
题目大意:求每个长度为\(k\)的区间的最小值和最大值。
  单调队列的模板题,可以用一个单调递增栈和一个单调递减栈分别来维护区间最小值与最大值。至于怎么控制区间长度,由队列的特性,队列越靠前的元素肯定越靠近区间左端,所以每次只要检查队首的元素是否在区间之外并弹出就是了。

const int maxn = 1e6+10;
int n, k, arr[maxn]; P ans[maxn];
deque<P> maxx, minn;
int main(void) {
    scanf("%d%d", &n, &k);
    for (int i = 0; i<n; ++i) scanf("%d", &arr[i]);
    for (int i = 0; i<n; ++i) {
        if(!minn.empty() && minn.front().second<=i-k) minn.pop_front();
        while(!minn.empty() && minn.back().first>=arr[i]) minn.pop_back();
        if(!maxx.empty() && maxx.front().second<=i-k) maxx.pop_front();
        while(!maxx.empty() && maxx.back().first<=arr[i]) maxx.pop_back();
        maxx.push_back(P(arr[i], i));
        minn.push_back(P(arr[i], i));
        ans[i] = P(minn.front().first, maxx.front().first);
    } 
    for (int i = k-1; i<n; ++i) printf(i==n-1? "%d\n":"%d ", ans[i].first);
    for (int i = k-1; i<n; ++i) printf(i==n-1? "%d\n":"%d ", ans[i].second);
    return 0;
}
posted @ 2020-04-17 23:14  shuitiangong  阅读(86)  评论(0编辑  收藏  举报