CDOJ 1591 An easy problem A

N个数排成一列,Q个询问,每次询问一段区间内的数的极差是多少。

Input

第一行两个整数N(1≤N≤50000),Q(1≤Q≤200000)。接下来一行N个整数a1 a2 a3 ....an,(1≤ai≤1000000000)。接下来Q行,每行两个整数L,R(1≤L≤R≤N)。

Output

对于每个询问输出一行,一个整数表示区间内的极差。

Sample input and output

Sample InputSample Output
5 3
3 2 7 9 10
1 5
2 3
3 5
8
5
3
#include <iostream>
using namespace std;
int N,Q,L,R,a[50010];
struct tree {
    int l,r,Max,Min;
} tr[200010];
void build(int x,int y,int root) {
    tr[root].l=x;
    tr[root].r=y;
    if (x==y) {
        tr[root].Max=a[x];
        tr[root].Min=a[x];
        return;
    }
    int mid=(x+y)>>1;
    build(x, mid, root<<1);
    build(mid+1, y, (root<<1)+1);
    tr[root].Max=max(tr[root<<1].Max,tr[(root<<1)+1].Max);
    tr[root].Min=min(tr[root<<1].Min,tr[(root<<1)+1].Min);
}
int query_max(int x,int y,int root) {
    if (x==tr[root].l&&y==tr[root].r) return tr[root].Max;
    int mid=(tr[root].l+tr[root].r)>>1;
    if (x>mid) return query_max(x, y, (root<<1)+1);
    if (y<=mid) return query_max(x, y, root<<1);
    return max(query_max(x, mid, root<<1),query_max(mid+1, y, (root<<1)+1));
}
int query_min(int x,int y,int root) {
    if (x==tr[root].l&&y==tr[root].r) return tr[root].Min;
    int mid=(tr[root].l+tr[root].r)>>1;
    if (x>mid) return query_min(x, y, (root<<1)+1);
    if (y<=mid) return query_min(x, y, root<<1);
    return min(query_min(x, mid, root<<1),query_min(mid+1, y, (root<<1)+1));
}
int main() {
    scanf("%d%d",&N,&Q);
    for (int i=1; i<=N; i++) {
        scanf("%d",&a[i]);
    }
    build(1, N, 1);
    for (int i=0; i<Q; i++) {
        scanf("%d%d",&L,&R);
        printf("%d\n",query_max(L, R, 1)-query_min(L, R, 1));
    }
}
posted @ 2017-12-04 23:23  soildom  阅读(206)  评论(0编辑  收藏  举报