• poj3264 Balanced Lineup(树状数组)


    Balanced Lineup
    Time Limit: 5000MS   Memory Limit: 65536K
    Total Submissions: 64655   Accepted: 30135
    Case Time Limit: 2000MS

    Description

    For the daily milking, Farmer John's N cows (1 ≤ N ≤ 50,000) always line up in the same order. One day Farmer John decides to organize a game of Ultimate Frisbee with some of the cows. To keep things simple, he will take a contiguous range of cows from the milking lineup to play the game. However, for all the cows to have fun they should not differ too much in height.

    Farmer John has made a list of Q (1 ≤ Q ≤ 200,000) potential groups of cows and their heights (1 ≤ height ≤ 1,000,000). For each group, he wants your help to determine the difference in height between the shortest and the tallest cow in the group.

    Input

    Line 1: Two space-separated integers, N and Q.
    Lines 2..N+1: Line i+1 contains a single integer that is the height of cow i
    Lines N+2..N+Q+1: Two integers A and B (1 ≤ ABN), representing the range of cows from A to B inclusive.

    Output

    Lines 1..Q: Each line contains a single integer that is a response to a reply and indicates the difference in height between the tallest and shortest cow in the range.

    Sample Input

    6 3
    1
    7
    3
    4
    2
    5
    1 5
    4 6
    2 2

    Sample Output

    6
    3
    0

    Source

    题意:就是求区间[l,r]的最大值与最小值之差
    首先,介绍一下树状数组,树状数组的复杂度为O(logn),之所以这么快,它是用到了分块优化的思想
    ,比如:1-5就分为1、1-2、3、1-2-3-4、5;而树状数组最基本实现的就是求前缀和和区间单点更新;在本题中,我们也能效仿这样吗,当然。单点更新极值的话跟之前的一样;重点是求区间的极值,我们不能像求前缀和一样sum[r]-sum[l],那应该怎么办呢?
    其实这里还是用到分块优化的思想,但是我们不能直接用Max[r],因为这里表示区间可能超出了我们要求的区间,但是我们可以利用一些包含在[l,r]这里面的块,从而降低复杂度。
    假设我们暴力的话,就是从右往左遍历一遍a数组然后取最值,那么在这之中,如果有一些分块在[l,r]之中,就可以直接使用这些块了,就不用去遍历他们,但是遇到有的块超出了[l,r],我们就只能直接比较a[r]了。
    代码:
    #include<iostream>
    #include<string.h>
    using namespace std;
    typedef long long ll;
    typedef unsigned long long ull;
    #define mod 1000000007
    #define INF 0x3f3f3f3f
    #define MAX 50005
    int Max[MAX],Min[MAX];
    int a[MAX];
    int n,q;
    inline void read(int &x){
        char ch;
        bool flag=false;
        for (ch=getchar();!isdigit(ch);ch=getchar())if (ch=='-') flag=true;
        for (x=0;isdigit(ch);x=x*10+ch-'0',ch=getchar());
        x=flag?-x:x;
    }
    inline void write(int x){
        static const int maxlen=100;
        static char s[maxlen];
            if (x<0) {   putchar('-'); x=-x;}
        if(!x){ putchar('0'); return; }
        int len=0; for(;x;x/=10) s[len++]=x % 10+'0';
        for(int i=len-1;i>=0;--i) putchar(s[i]);
    }
    int lowbit(int x)
    {
        return x&-x;
    }
    void updata(int i,int val)
    {
        while(i<=n)
        {
            Min[i]=min(Min[i],val);
            Max[i]=max(Max[i],val);
            i+=lowbit(i);
        }
    }
    int query(int l,int r)
    {
        int maxn=a[l],minn=a[r];
        while(1)
        {
            maxn=max(maxn,a[r]),minn=min(minn,a[r]);
            if(l==r) break;
            for(r-=1;r-l>=lowbit(r);r-=lowbit(r))
                maxn=max(Max[r],maxn),minn=min(minn,Min[r]);
        }
        return maxn-minn;
    }
    int main()
    {
        memset(Min,INF,sizeof(Min));
        read(n);read(q);
        for(int i=1;i<=n;i++){
            read(a[i]);
            updata(i,a[i]);
        }
        while(q--)
        {
            int a,b;
            read(a),read(b);
            write(query(a,b));
            putchar('
    ');
        }
        return 0;
    }

    时间复杂度近似为log2(n)。

    参考博客:https://www.cnblogs.com/mypride/p/5002556.html

                    https://blog.csdn.net/u012602144/article/details/52734329

     
  • 相关阅读:
    一个万能的工具包下载网站
    Keras框架简介
    发现了一个非常棒的pyqt5的例子集
    人脸识别常用数据集大全(12/20更新)
    用 opencv和numpy进行图片和字符串互转,并保存至 json
    机器学习中的范数规则化-L0,L1和L2范式(转载)
    利用face_recognition库裁取人脸
    一招解决C盘空间不足,再也不怕硬盘爆满!
    【LeetCode】394.字符串解码(辅助栈、递归、详细图解)
    程序员那些事儿:女婿程序员
  • 原文地址:https://www.cnblogs.com/zhgyki/p/9545316.html
Copyright © 2020-2023  润新知