• $P1440 求m区间内的最小值$


    (problem)

    线段树 求 (RMQ)问题 (orz) 原因是因为我的(ST)表炸了
    (我太弱了)
    (RMQ)问题通常是求区间最值。 比如说 :(X - Y)的最大值?
    这样的问题往往无从下手 我们需要一个解决(RMQ)问题的算法。
    比如说是:(ST)表 , 线段树。
    其实还有单调队列的方法。 其他题解也说到了。(代码简短)
    可我还是不知道为什么我选了 (ST)表 && 线段树。
    可能是因为我比较笨吧(大雾
    先讲讲(ST)表吧 虽然说不能(AC) 但是我看见有人 用这个方法(AC)
    (ST)表的思路主要是 预处理 然后 (O(1))复杂度的查询 适合这种问题
    用一个(f[i][j]) 来 表示 (i) ~ $ i + 2^j(的最大值 从而到这样 这样子时间是完全)ojbk$的 但是反观 内存 (n log n)的一个内存 (N<=200w) 所以显然不行
    (如果有哪位神仙用(ST)表AC了麻烦点评测记录告诉我如何不(MLE))
    评测记录:(Here)
    所以去想线段树 线段树的查询大概是(log n)
    (n log n) 也勉强过得去吧。
    但是貌似没有单调队列快(还不是我弱)
    回归正题 线段树 (分治的方法
    首先我们需要定义数组 以及 建树

    const int N = 2e6 + 10 ;
    struct node {
        int l , r , w ;
    #define lt k << 1
    #define rt k << 1 | 1
    }tree[N << 2] ;
    

    不要问我为啥(<<2) 因为我也不知道 线段树的数组大小通常是(N)(4)

    inline void build(int k,int l,int r) {
        if(l > r) return ;
        if(l == r) {
            tree[k].l = l , tree[k].r = r , tree[k].w = a[l] ;
            return ;
        }
        int mid = (l + r) >> 1 ;//分治Here
        build(lt , l , mid) ;
        build(rt , mid + 1 , r) ;
        tree[k].l = l , tree[k].r = r ;
        tree[k].w = min(tree[lt].w , tree[rt].w) ;
    }
    

    建完树之后我们需要做一个操作 : (query)(当然只是函数名我个人喜欢这种函数名)

    inline int query(int k,int l,int r,int x,int y) {
        if(l > r) return 0 ;
        if(l >= x and r <= y) return tree[k].w ;
        int mid = (l + r) >> 1 ;
        int sum = inf ;
        if(x <= mid) sum = min(sum , query(lt , l , mid , x , y)) ;//分治
        if(y > mid) sum = min(sum , query(rt , mid + 1 , r , x , y)) ;
        return sum ;
    }
    

    所以易证时间复杂度 $O(nlog n) $

    空间复杂度 (O(N*4))

    #include <bits/stdc++.h>
    using namespace std ;
    
    inline int rd() { int x = 0 ; int f = 1 ; register char c ;
    #define gc c = getchar()
        while(isspace(gc)) ;
        if(c == '-') f = -1 , gc ;
        while(x = (x<<1) + (x<<3) + (c&15) , isdigit(gc)) ;
        return x * f ;
    #undef gc
    }
    
    const int inf = INT_MAX >> 1 ;
    const int N = 2e6 + 10 ;
    
    struct node {
        int l , r , w ;
    #define lt k << 1
    #define rt k << 1 | 1
    }tree[N << 2] ;
    
    int n , m ;
    int a[N] ;
    
    inline void build(int k,int l,int r) {
        if(l > r) return ;
        if(l == r) {
            tree[k].l = l , tree[k].r = r , tree[k].w = a[l] ;
            return ;
        }
        int mid = (l + r) >> 1 ;
        build(lt , l , mid) ;
        build(rt , mid + 1 , r) ;
        tree[k].l = l , tree[k].r = r ;
        tree[k].w = min(tree[lt].w , tree[rt].w) ;
    }
    
    inline int query(int k,int l,int r,int x,int y) {
        if(l > r) return 0 ;
        if(l >= x and r <= y) return tree[k].w ;
        int mid = (l + r) >> 1 ;
        int sum = inf ;
        if(x <= mid) sum = min(sum , query(lt , l , mid , x , y)) ;
        if(y > mid) sum = min(sum , query(rt , mid + 1 , r , x , y)) ;
        return sum ;
    }
    
    signed main() {
        n = rd() , m = rd() ;
        for(register int i=1;i<=n;i++) a[i] = rd() ;
        build(1 , 1 , n) ;
        for(register int i=1;i<=n;i++) {
            int x = i - m , y = i - 1 ;
            if(x <= 0) x = 1 ;
            if(x > y) {
                puts("0") ;
                continue ;
            }
            printf("%d
    " , query(1 , 1 , n , x , y)) ;
        }
        return 0 ;
    }
    
  • 相关阅读:
    如何节省 1TB 图片带宽?解密极致图像压缩
    微信亿级用户异常检测框架的设计与实践
    一文带你深度解析腾讯云直播答题方案
    kafka数据迁移实践
    揭密微信跳一跳小游戏那些外挂
    从蓝光到4K,腾讯视频高码率下载背后的技术
    GridControl列自动匹配宽度
    access的逻辑类型
    NPOI Excel类
    Access sql语句创建表及字段类型
  • 原文地址:https://www.cnblogs.com/qf-breeze/p/10738659.html
Copyright © 2020-2023  润新知