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
  • 相关阅读:
    DS博客作业06--图
    DS博客作业05--树
    DS博客作业03--栈和队列
    DS博客作业02--线性表
    DS博客作业01--日期抽象数据类型设计与实现
    C语言博客作业06--结构体&文件
    c语言博客作业05--指针
    C语言博客作业03--函数
    DS博客作业--课程总结
    DS博客作业07--查找
  • 原文地址:https://www.cnblogs.com/tanglizi/p/8461993.html
Copyright © 2011-2022 走看看