zoukankan      html  css  js  c++  java
  • 滑动窗口(poj,线段树维护区间最值)

    题目描述

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

    例如:

    The array is [1 3 -1 -3 5 3 6 7], and k = 3.

    输入输出格式

    输入格式:

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

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

    输出格式:

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

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

    说明

    50%的数据,n<=10^5

    100%的数据,n<=10^6

    思路:

    一般人切这道题都用的st表或者是单调队列

    我手残打了个线段树(其实是因为我太菜了不会上面两个

    我线段树维护两个值,一个是区间最大值,一个是区间最小值

    每次修改,在修改完叶子结点(单点插入,我当做修改处理)后,我向上pushup更新区间最值

    每个节点表示的是他所负责的线段的区间最值

    查询常规查询即可

    代码:

    // luogu-judger-enable-o2
    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #define rii register int i
    #define rij register int j
    #define rs 1048576
    #define inf 1<<30
    using namespace std;
    struct nod{
        long long ma,mi;
    }x[7000005];
    int n,k;
    void add(long long wz,long long l,long long r,long long val,long long bh)
    {
        if(l==r&&l==wz)
        {
            x[bh].mi=val;
            x[bh].ma=val;
            return;
        }
        long long ltt=(l+r)/2;
        if(wz>ltt)
        {
            add(wz,ltt+1,r,val,bh*2+1);
        }
        else
        {
            add(wz,l,ltt,val,bh*2);
        }
        x[bh].mi=min(x[bh*2].mi,x[bh*2+1].mi);
        x[bh].ma=max(x[bh*2].ma,x[bh*2+1].ma);
    }
    struct cs{
        int maxn,minx;
    }ans;
    cs query(long long l,long long r,long long nl,long long nr,long long bh)
    {
        if(l<nl)
        {
            l=nl;
        }
        if(r>nr)
        {
            r=nr;
        }
        cs an,bn;
        an.maxn=-inf;
        an.minx=inf;
        bn.maxn=-inf;
        bn.minx=inf;
        if(l==nl&&r==nr)
        {
            int ltt=x[bh].ma;
            int kkk=x[bh].mi;
            an.maxn=ltt;
            an.minx=kkk;
            return an;
        }
        int ltt=(nl+nr)/2;
        if(l<=ltt)
        {
            an=query(l,r,nl,ltt,bh*2);
        }
        if(r>ltt)
        {
            bn=query(l,r,ltt+1,nr,bh*2+1);
        }
        an.maxn=max(an.maxn,bn.maxn);
        an.minx=min(an.minx,bn.minx);
        return an;
    }
    long long minn[1000005];
    int main()
    {
        for(rii=1;i<=7000005;i++)
        {
            x[i].ma=-inf;
            x[i].mi=inf;
        }
        scanf("%d%d",&n,&k);
        for(rii=1;i<=n;i++)
        {
            long long ltt;
            scanf("%lld",&ltt);
            add(i,1,rs,ltt,1);
        }
        for(rii=1;i<=n-k+1;i++)
        {
            ans=query(i,i+k-1,1,rs,1);
            printf("%d ",ans.minx);
            minn[i]=ans.maxn;
        }
        printf("
    ");
        for(rii=1;i<=n-k+1;i++)
        {
            printf("%d ",minn[i]);
        }
    }
  • 相关阅读:
    微信小程序退款【证书的使用】
    生成随机位数的UUID
    弹出层-layui
    load加载层-layui
    form-layui
    table-layui
    下拉列表模仿placeholder效果
    .net core 2.0 Unable to convert MySQL date/time to System.DateTime
    .net core Include问题
    .net core 2.0 配置Session
  • 原文地址:https://www.cnblogs.com/ztz11/p/9342065.html
Copyright © 2011-2022 走看看