poj--2823 Sliding Window(单调队列)

来源:互联网 发布:dubstep软件怎么用 编辑:程序博客网 时间:2024/06/15 04:46

poj 2823

题解

滑动窗口的最大最小值问题,典型的单调队列应用。
所谓单调队列,顾名思义,队列是单调的,即队列里的元素严格的递增或递减,这意味着队首元素总是最小值或最大值,这是一个很有用的性质。

单调队列支持两种操作,队首删除,队尾插入或删除。
以求最小值为例,需要维护一个单调递增队列,每次有新元素要入队的时候,删除队尾元素直到队尾元素小于该新元素或队列空。
在此题背景下,窗口每滑一格,意味着要删除滑动前窗口的最左边元素,如果该元素是队首元素,则进行队首删除操作(即队列的大小比窗口更大),然后新元素入队。

#include <iostream>#include <cstdio>#include <set>#include <queue>#include <vector>#include <algorithm>using namespace std;const int maxn = 1000000 + 10;int   a[maxn];int   n, k;// TLEvoid solve(){    set<int> ValQue;    vector<int> maxAns, minAns;    for(int i = 0; i < k; ++i){        ValQue.insert(a[i]);    }    minAns.push_back(*ValQue.begin());    maxAns.push_back(*ValQue.rbegin());    for(int i = k; i < n; ++i){        ValQue.erase(a[i - k]);        ValQue.insert(a[i]);        minAns.push_back(*ValQue.begin());        maxAns.push_back(*ValQue.rbegin());    }    for(int i = 0; i < (int)minAns.size(); ++i) printf("%d ", minAns[i]);    printf("\n");    for(int i = 0; i < (int)maxAns.size(); ++i) printf("%d ", maxAns[i]);    printf("\n");}struct Que{    int val;    int pos;    Que(int v, int p):val(v), pos(p){}    Que(){}};Que maxQue[maxn];Que minQue[maxn];// C++ 12432K   5454MSvoid solve2(){    vector<int> maxAns, minAns;    int minHead = 0, minTail = 0;    int maxHead = 0, maxTail = 0;    for(int i = 0; i < k; ++i){        while(minHead < minTail && minQue[minTail - 1].val >= a[i]) --minTail;        minQue[minTail++] = Que(a[i], i);        while(maxHead < maxTail && maxQue[maxTail - 1].val <= a[i]) --maxTail;        maxQue[maxTail++] = Que(a[i], i);    }    for(int i = k; i < n; ++i){        maxAns.push_back(maxQue[maxHead].val);        minAns.push_back(minQue[minHead].val);        // 处理单调递增队列        while(minHead < minTail && i - minQue[minHead].pos >= k) ++minHead; //队头删除        while(minHead < minTail && minQue[minTail - 1].val >= a[i]) --minTail; //队尾插入        minQue[minTail++] = Que(a[i], i);        // 处理单调递减队列        while(maxHead < maxTail && i - maxQue[maxHead].pos >= k) ++maxHead; //队头删除        while(maxHead < maxTail && maxQue[maxTail - 1].val <= a[i]) --maxTail; //队尾插入        maxQue[maxTail++] = Que(a[i], i);    }    maxAns.push_back(maxQue[maxHead].val);    minAns.push_back(minQue[minHead].val);    for(int i = 0; i < (int)minAns.size(); ++i) printf("%d ", minAns[i]);    printf("\n");    for(int i = 0; i < (int)maxAns.size(); ++i) printf("%d ", maxAns[i]);    printf("\n");}int main(){    while(cin >> n >> k){        for(int i = 0; i < n; ++i) scanf("%d", a + i);        solve2();    }    return 0;}
0 0
原创粉丝点击