1. 程式人生 > >樹狀陣列求區間最值

樹狀陣列求區間最值

1627: 極差
Time Limit: 1 Sec Memory Limit: 128 MB

[Submit][Status][Web Board]
Description

還記得高中數學的統計部分的極差嗎?既然你能上zcmu計算機及其相關專業,想必計算能力是很厲害的,有一個實驗得到n個數,做實驗的同學經常問你某個區間[L,R]的範圍誤差。(資料範圍[1,100000])

Input

輸入兩個數n,m,第二行n個數,接下來m行[L,R ]

Output

輸出:每一個[L,R]的誤差範圍

Sample Input

3 2
1 5 10
1 2
2 3

Sample Output

4
5

HINT

範圍誤差在數學上用極差表示,極差是區間的最大值與最小值的差

Source

zcc

[Submit][Status][Web Board]

第一次時間超限程式碼:
/*
即使我知道百分之90時間超限,但是我有我想鞏固的東西–>為了用用藉助結構體封裝陣列來實現陣列之間賦值
*/
程式碼~:

#include <stdio.h>
#include <string.h>
#include <algorithm>
using namespace std;
typedef struct date
{
    int num[100005];
} DATE;
DATE a,b;
int main()
{
    int n,m;
    while(~scanf("%d%d",&n,&m))
    {
        memset(a.num,0,sizeof(a.num));
        for(int i = 0; i < n; i++)
        {
            scanf("%d",&a.num[i]);
        }
        while(m--)
        {
            int L,R;
            scanf("%d%d",&L,&R);
            b = a;
            sort(b.num+L-1,b.num+L+R-2);
                printf("%d\n",b.num[R-1] - b.num[L-1]);
        }
    }
    return 0;
}

下面是AC程式碼(效率不知為啥比較低~,耗時1600ms,ac了):
/*
說實話自己對陣列陣列理解還是比較欠缺(自己還得多研究!!!),
但是我用它來寫,還特意用了函式指標,加深了我對函式指標的理解
*/
AC程式碼~:

#include <stdio.h>
#include <algorithm>
using namespace std;
#define max_t 100005
#define Inf 0x3f3f3f3f
int n,m;
int a[max_t],c[max_t],c_max[max_t],c_min[max_t];
int (*f)(int,int);
int Max(int x,int y)
{
    return x>y?x:y;
}
int Min(int x,int y)
{
    return x<y?x:y;
}
int lowbit(int x)
{
    return x&-x;
}
/*int SUM(int y)
{
    int sum = 0;
    for(int i = y; i > 0; i-=lowbit(i))
        sum += c[i];
    return sum;
}
void update(int x,int k)
{
    for(int i = x; i <= n; i+=lowbit(i))
        c[i] += k;
}*/
void up_max_min(int x,int k,int(*f)(int,int),int c_max[])
{
    for(int i = x; i <= n; i+=lowbit(i))
        c_max[i] = f(k,c_max[i]);
}
int get_max_min(int L,int R,int(*f)(int,int),int c_max[])
{
    int y = a[R];
    while(1)
    {
        y = f(y,a[R]);
        if(L==R) break;
        for(R--; R-L>=lowbit(R); R-=lowbit(R))
            y = f(y,c_max[R]);
    }
    return y;
}
int main()
{
    while(~scanf("%d%d",&n,&m))
    {
        fill(c,c+n+1,0);
        fill(c_max,c_max+n+1,0);
        fill(c_min,c_min+n+1,Inf);
        for(int i = 1; i <= n; i++)
        {
            scanf("%d",&a[i]);
            f = Max;
            up_max_min(i,a[i],f,c_max);
            f = Min;
            up_max_min(i,a[i],f,c_min);
        }
        while(m--)
        {
            int L,R,p,q,t;
            scanf("%d%d",&L,&R);
            R>L?(t =0):(t=L,L=R,R=t);
            f = Max;
            p = get_max_min(L,R,f,c_max);
            f = Min;
            q = get_max_min(L,R,f,c_min);
            printf("%d\n",p-q);
        }
    }
    return 0;
}
/*

總結:
不過多解釋,自己還得多研究~
*/