1. 程式人生 > >poj3264 Balanced Lineup(樹狀數組)

poj3264 Balanced Lineup(樹狀數組)

基本 最值 git dai acc short pri ren neu

題目傳送門 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

USACO 2007 January Silver 題意:就是求區間[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(\n);
    }
    return 0;
}

時間復雜度近似為log2(n)。

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

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

poj3264 Balanced Lineup(樹狀數組)