• 博客园logo
  • 会员
  • 众包
  • 新闻
  • 博问
  • 闪存
  • 赞助商
  • HarmonyOS
  • Chat2DB
    • 搜索
      所有博客
    • 搜索
      当前博客
  • 写随笔 我的博客 短消息 简洁模式
    用户头像
    我的博客 我的园子 账号设置 会员中心 简洁模式 ... 退出登录
    注册 登录
MZQ667
博客园    首页    新随笔    联系   管理    订阅  订阅

[Luogu] P1886 滑动窗口

Luogu P1886 滑动窗口


传送门

此题为单调队列入门题。单调队列,可以\(O(n)\)求一段数列中区间极值。记录队列中元素大小与该元素在原数组中的位置。当队首元素超出当前求值区间时,头指针加一;当当前将入队元素大于或小于尾元素时,尾指针减一,直到不符合上一条件时,将当前元素入队。然后要求极值只需输出队首元素即可。

#include <cstdio>
const int MAXN = 1000001;
int n, k;
int a[MAXN], que[MAXN], id[MAXN], head, tail;
int main() {
    scanf("%d%d", &n, &k);
    for (int i = 1; i <= n; ++i)
        scanf("%d", &a[i]);
    head = 1; tail = 0;
    for (int i = 1; i <= n; ++i) {
        while(head <= tail && id[head] <= i - k) head++;
        while(head <= tail && que[tail] >= a[i]) tail--;
        que[++tail] = a[i]; id[tail] = i;
        if(i >= k) printf("%d ", que[head]);
    }
    printf("\n");
    head = 1; tail = 0;
    for (int i = 1; i <= n; ++i) {
        while(head <= tail && id[head] <= i - k) head++;
        while(head <= tail && que[tail] <= a[i]) tail--;
        que[++tail] = a[i]; id[tail] = i;
        if(i >= k) printf("%d ", que[head]);
    }
    printf("\n");
    return 0;
}
知识共享许可协议
本作品采用知识共享署名-相同方式共享 4.0 国际许可协议进行许可。
posted @ 2018-03-12 17:55  mzq667  阅读(183)  评论(0)    收藏  举报
刷新页面返回顶部
博客园  ©  2004-2025
浙公网安备 33010602011771号 浙ICP备2021040463号-3