AOJ-AHU-OJ-351 求最值之差

来源:互联网 发布:怎么开农村淘宝服务站 编辑:程序博客网 时间:2024/06/06 02:16
求最值之差
Time Limit: 1000 ms   Case Time Limit: 1000 ms   Memory Limit: 64 MB
Description
给出N个数,求第a个数到第b个数之间最大的数减去最小的数的结果

Input
N(N小于100,000),M(M小于100,000)
接下来有N个数
接下来M组范围,所有数均在[0,231-1]内
每个范围有2个整数a,b(1<=a<=b<=N)


Output
每行输出一个结果

Sample Input
OriginalTransformed
5 34 2 5 1 101 52 32 2

Sample Output
OriginalTransformed
930

————————————————————开森的分割线————————————————————

思路:学了NotOnlySuccess的HDU上的敌兵布阵的线段树之后,拿这道题目练一练手。毕竟线段树时间复杂度是O(logN)嘛!此题不一样的地方就在于不求和,求差。而且多了一样东西“最值”。灰常容易想到的方法,就是建立两棵树,一棵存最大值,另一棵存最小值。需要的时候,查询并且返回需要的最值,作差即可。注意!运用带参数的宏定义的时候,小心不要进行重复运算。否则一不小心就把你的复杂度乘以2了。

代码如下:

#include <stdio.h>#include <string.h>#include <math.h>#include <stdlib.h>#define N 100010#define lson l, m, id << 1#define rson m+1, r, id << 1 | 1#define maxi(a, b) (a > b ? a : b)#define mini(a, b) (a < b ? a : b)int Max[N<<2], Min[N<<2];void FindM(int id) {//构建最值树    Max[id] = maxi(Max[id<<1], Max[id<<1|1]);    Min[id] = mini(Min[id<<1], Min[id<<1|1]);}void build(int l, int r, int id) {    if(l == r) {        scanf("%d", Max+id);        Min[id] = Max[id];        return ;    }    int m = (l+r) >> 1;    build(lson); build(rson);//左右开弓    FindM(id);}int Q1(int L, int R, int l, int r, int id) {//询问函数1,询问最大值    if(L <= l&&r <= R)        return Max[id];    int m = (l+r) >> 1;    int ans = 0;    if (L <= m) {        int u1 = Q1(L, R, lson);        ans = maxi(ans, u1);//注意,借助新变量使用宏定义,避免复杂度×2    }    if (R > m) {        int u2 = Q1(L, R, rson);        ans = maxi(ans, u2);    }    return ans;//最终return的一定是它}int Q2(int L, int R, int l, int r, int id) {    if(L <= l&&r <= R)        return Min[id];    int m = (l+r) >> 1;    int res = 2147483647;    if (L <= m) {        int u1 = Q2(L, R, lson);        res = mini(res, u1);    }    if (R > m) {        int u2 = Q2(L, R, rson);        res = mini(res, u2);    }    return res;}int main() {int len, cas;scanf("%d%d", &len, &cas);build(1, len, 1);    /*for(int i = 1; i <= len << 2; i++)        printf("%d ", Max[i]);    puts("");    for(int i = 1; i <= len << 2; i++)        printf("%d ", Min[i]);        */    while(cas--) {        int A, B;        scanf("%d%d", &A, &B);        if(A == B)        printf("0\n");        else        printf("%d\n", Q1(A, B, 1, len, 1) - Q2(A, B, 1, len, 1));    }return 0;}


0 0