zoukankan      html  css  js  c++  java
  • 【洛谷】【线段树】P1886 滑动窗口

    【题目描述:】

    现在有一堆数字共N个数字(N<=10^6),以及一个大小为k的窗口。现在这个从左边开始向右滑动,每次滑动一个单位,求出每次滑动后窗口中的最大值和最小值。

    【输入格式:】

    输入一共有两行,第一行为n,k。

    第二行为n个数(<INT_MAX).

    【输出格式:】

    输出共两行,第一行为每次窗口滑动的最小值

    第二行为每次窗口滑动的最大值

    输入样例#18 3
    1 3 -1 -3 5 3 6 7
    
    输出样例#1-1 -3 -3 -3 3 3
    3 3 5 5 6 7
    输入输出样例

    【算法分析:】 

    线段树使用结构体同时维护区间最小值和最大值

    没有修改只有建树和查询操作,更优的方法是使用st表做RMQ

    板子题.

    【代码:】

     1 //滑动窗口
     2 #include<iostream>
     3 #include<cstdio>
     4 using namespace std;
     5 
     6 const int MAXN = 1e6 + 1;
     7 
     8 int n, k;
     9 int a[MAXN];
    10 struct Segment {
    11     int maxn, minn;
    12 }t[MAXN << 2];
    13 
    14 void Build(int o, int l, int r) {
    15     if(l == r) t[o].maxn = t[o].minn = a[l];
    16     else {
    17         int mid = (l + r) >> 1;
    18         Build(o << 1, l , mid);
    19         Build(o << 1|1, mid + 1, r);
    20         t[o].maxn = max(t[o << 1].maxn, t[o << 1|1].maxn);
    21         t[o].minn = min(t[o << 1].minn, t[o << 1|1].minn);
    22     }
    23 }
    24 int max_ans, min_ans;
    25 void Query(int o, int l, int r, int ql, int qr) {
    26     if(ql <= l && r <= qr) {
    27         max_ans = max(max_ans, t[o].maxn);
    28         min_ans = min(min_ans, t[o].minn);
    29     }
    30     else {
    31         int mid = (l + r) >> 1;
    32         if(ql <= mid) Query(o << 1, l, mid, ql, qr);
    33         if(qr > mid) Query(o << 1|1, mid + 1, r, ql, qr);
    34     }
    35 }
    36 
    37 int ans1[MAXN], ans2[MAXN];
    38 int main() {
    39     scanf("%d%d", &n, &k);
    40     for(int i = 1; i <= n; ++i)
    41         scanf("%d", &a[i]);
    42     Build(1, 1, n);
    43     for(int i = 1; i + k - 1 <= n; ++i) {
    44         max_ans = -2e9, min_ans = 2e9;
    45         Query(1, 1, n, i, i + k - 1);
    46         ans1[i] = max_ans, ans2[i] = min_ans;
    47     }
    48     for(int i = 1; i <= n - k + 1; ++i) printf("%d ", ans2[i]);
    49     putchar('
    ');
    50     for(int i = 1; i <= n - k + 1; ++i) printf("%d ", ans1[i]);
    51 }
  • 相关阅读:
    第四百九十六天 how can I 坚持
    第四百九十四、五天 how can I 坚持
    第四百九十三天 how can I 坚持
    第四百九十二天 how can I 坚持
    第四百九十一天 how can I 坚持
    第四百九十天 how can I 坚持
    第四百八十九天 how can I 坚持
    第四百八十八天 how can I 坚持
    第四百八十七天 how can I 坚持
    第四百八十六天 how can I 坚持
  • 原文地址:https://www.cnblogs.com/devilk-sjj/p/9043200.html
Copyright © 2011-2022 走看看