HZNU-ACM寒假集训Day10小结 单调栈-单调队列

 数据结构往往可以在不改变主算法的前提下题高运行效率,具体做法可能千差万别,但思路却是有规律可循

 经典问题:滑动窗口  单调队列O(n)

 POJ 2823 

 我开始写的: TLE 说明STL的库还是有点慢

#include<iostream>
#include<cstdio>
#include<string>
#include<algorithm>
#include<queue>
#include<deque>
#include<set>
#include<map>
#include<cmath>
#include<stack>
const double PI = acos(-1.0);
#define INF 0x3f3f3f3f
typedef long long ll;
using namespace std;


struct Deq {
    int idx;
    int w;
};

deque<Deq> q;
deque<Deq> qq;
int Max[1000005];

int main() {
    int n, k;
    int x;
    int cnt = 0;
    scanf("%d%d", &n, &k);
    for (int i = 0; i < n; i++) {
        if (i < k) {
            scanf("%d", &x);
            Deq qqq;
            qqq.idx = i;
            qqq.w = x;
            if (q.empty()) q.push_back(qqq);
            if (qq.empty()) qq.push_back(qqq);
            else {
                while (!q.empty() && q.back().w < x) q.pop_back();
                q.push_back(qqq);
                while (!qq.empty() && qq.back().w > x) qq.pop_back();
                qq.push_back(qqq);
            }
            if (i == k - 1) {
                printf("%d", qq.front().w);
                Max[cnt++] = q.front().w;
            }
        }
        else {
            scanf("%d", &x);
            Deq qqq;
            qqq.idx = i;
            qqq.w = x;
            if (q.empty()) q.push_back(qqq);
            if (qq.empty()) qq.push_back(qqq);
            else {
                while (!q.empty() && q.back().w < x) q.pop_back();
                q.push_back(qqq);
                while (!qq.empty() && qq.back().w > x) qq.pop_back();
                qq.push_back(qqq);
            }
            while (q.front().idx < i + 1 - k) q.pop_front();
            while (qq.front().idx < i + 1 - k) qq.pop_front();
            printf(" %d", qq.front().w);
            Max[cnt++] = q.front().w;
        }
    }
    printf("\n");
    for (int i = 0; i < cnt; i++) {
        i == 0 ? printf("%d", Max[i]) : printf(" %d", Max[i]);
    }
    return 0;
}
View Code

 洛谷题解:

  直接用下标存进队列 手写双端队列

#include<iostream>
#include<cstdio>
#include<string>
#include<algorithm>
#include<queue>
#include<deque>
#include<set>
#include<map>
#include<cmath>
#include<stack>
const double PI = acos(-1.0);
#define INF 0x3f3f3f3f
typedef long long ll;
using namespace std;

const int maxn = 1000005;
int n, m;
int q1[maxn], q2[maxn];
int a[maxn];

void Min_que() {
    int h = 1;     //head
    int t = 0;     //tail
    for (int i = 1; i <= n; i++) {
        while (h <= t && q1[h] + m <= i)    h++;
        while (h <= t && a[i] < a[q1[t]]) t--;
        q1[++t] = i;
        if (i >= m) printf("%d ", a[q1[h]]);
    }
    printf("\n");
}

void Max_que() {
    int h = 1;
    int t = 0;
    for (int i = 1; i <= n; i++) {
        while (h <= t && q2[h] + m <= i) h++;
        while (h <= t && a[i] > a[q2[t]]) t--;
        q2[++t] = i;
        if (i >= m) printf("%d ", a[q2[h]]);
    }
}

int main() {
    scanf("%d%d", &n, &m);
    for (int i = 1; i <= n; i++) scanf("%d", &a[i]);
    Min_que();
    Max_que();
    return 0;
}
View Code

  单调栈:

  

#include<iostream>
#include<cstdio>
#include<string>
#include<algorithm>
#include<queue>
#include<set>
#include<map>
#include<cmath>
#include<stack>
const double PI = acos(-1.0);
#define INF 0x3f3f3f3f
typedef long long ll;
using namespace std;


struct S {
    int idx;
    int w;
};
stack<S> s;
int a[3000005];
vector<int> f;

int main() {
    int n;
    scanf("%d", &n);
    for (int i = 0; i < n; i++) scanf("%d", &a[i]);
    for (int i = n - 1; i >= 0; i--) {
        if (i == n - 1) {
            f.push_back(0);
            s.push({ i,a[i] });
        }
        else {
            if (s.empty()) {
                f.push_back(0);
                s.push({ i,a[i] });
            }
            else {
                while (!s.empty()&&s.top().w <= a[i]) s.pop();
                if (!s.empty()) f.push_back(s.top().idx+1);
                else f.push_back(0);
                s.push({ i,a[i] });
            }
        }
    }
    for (auto it = f.rbegin(); it != f.rend(); it++) {
        if (it == f.rbegin()) printf("%d", *it);
        else printf(" %d", *it);
    }
    return 0;
}
View Code

猜你喜欢

转载自www.cnblogs.com/hznumqf/p/12287009.html