zoukankan      html  css  js  c++  java
  • POJ-3264 Balanced Lineup 线段树

    题目链接:https://cn.vjudge.net/problem/POJ-3264

    题意

    给出N,Q
    在一个含有N个数的序列中,询问[a, b]中的最大值最小值差值Q次

    思路

    其实就是查询区间最值

    • 一开始可以想到维护一个二维数组来存区间差值
      然而算了一下,空间根本不够
      没办法,写线段树吧
    • 用线段树的区间查询函数即可
    • 还有一种解决方法,就是ST算法(Sparse Table)
      O(nlog(n))的初始化,O(1)的查询
      空间是O(nlog(n))
      我的理解是ST算法主要进行了单个值的传递,最经典的例子是求区间最值
      当然最值问题也可以演变成很多问题,通解就是构造一个结构,写比较函数即可

    代码

    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    using namespace std;
    const int MAX=131072;
    int n, q, tmin[MAX+5], tmax[MAX+5], num[MAX+5];
    void pushUp(int root){
        tmax[root]=max(tmax[root<<1], tmax[root<<1|1]);
        tmin[root]=min(tmin[root<<1], tmin[root<<1|1]);
    }
    
    void build(int l, int r, int root){
        if (l==r){
            tmax[root]=tmin[root]=num[l];
            return ;
        }
    
        int mid=(l+r)>>1;
        build(l, mid, root<<1);
        build(mid+1, r, root<<1|1);
        pushUp(root);
    }
    
    int queryMax(int l, int r, int L, int R, int root){
        if (l<=L && R<=r) return tmax[root];
    
        int M=(L+R)>>1, ans=0;
        if (l<=M) ans=max(ans, queryMax(l, r, L, M, root<<1));
        if (r>=M+1) ans=max(ans, queryMax(l, r, M+1,R, root<<1|1));
        return ans;
    }
    
    int queryMin(int l, int r, int L, int R, int root){
        if (l<=L && R<=r) return tmin[root];
    
        int M=(L+R)>>1, ans=1000005;
        if (l<=M) ans=min(ans, queryMin(l, r, L, M, root<<1));
        if (r>=M+1) ans=min(ans, queryMin(l, r, M+1,R, root<<1|1));
        return ans;
    }
    
    int main(void){
        while (scanf("%d%d", &n, &q)==2){
            for (int i=1; i<=n; i++) scanf("%d", &num[i]);
            build(1, n, 1);
    
            int a, b;
            while (q--){
                scanf("%d%d", &a, &b);
                printf("%d
    ", queryMax(a, b, 1, n, 1) - queryMin(a, b, 1, n, 1));
            }
        }
    
        return 0;
    }
    
    
    Time Memory Length Lang Submitted
    3829ms 1572kB 1347 G++ 2018-02-22 20:19:52
  • 相关阅读:
    获取Mac地址
    GbkToUtf8 Utf8ToGbk PackHttp
    first Automation
    win32 Dll 中添加afx.h 出现如下错误 error LNK2005: _DllMain@12 already defined
    OpenSUSE 开启SSH 和网络设置
    systemctl命令用法详解
    浅谈Python的列表和链表
    用Python实现最大堆
    写一个解二阶魔方的程序
    暴力破解SixPack问题
  • 原文地址:https://www.cnblogs.com/tanglizi/p/8461993.html
Copyright © 2011-2022 走看看