思路:线段树
分析:
1 要求区间的最大值和最小值的差值
2 建立一棵线段树,节点保存这个区间的最大值和最小值,然后写两个查询函数,一个返回最大值一个返回最小值,然后相减即可。
代码:
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> using namespace std; #define MAXN 50010 int n , q; int height[MAXN]; struct Node{ int left; int right; int minNum; int maxNum; }; Node node[4*MAXN]; //建立线段树 void buildTree(int left , int right , int pos){ node[pos].left = left; node[pos].right = right; if(left == right){ node[pos].minNum = height[left]; node[pos].maxNum = height[left]; return; } int mid = (left+right)>>1; buildTree(left , mid , pos<<1); buildTree(mid+1 , right , (pos<<1)+1); node[pos].minNum = min(node[pos<<1].minNum , node[(pos<<1)+1].minNum); node[pos].maxNum = max(node[pos<<1].maxNum , node[(pos<<1)+1].maxNum); } //查询最大值 int queryMax(int left , int right , int pos){ if(node[pos].left == left && node[pos].right == right) return node[pos].maxNum; int mid = (node[pos].left+node[pos].right)>>1; if(right <= mid) return queryMax(left , right , pos<<1); else if(left > mid) return queryMax(left , right , (pos<<1)+1); else return max(queryMax(left , mid , pos<<1) , queryMax(mid+1 , right , (pos<<1)+1)); } //查询最小值 int queryMin(int left , int right , int pos){ if(node[pos].left == left && node[pos].right == right) return node[pos].minNum; int mid = (node[pos].left+node[pos].right)>>1; if(right <= mid) return queryMin(left , right , pos<<1); else if(left > mid) return queryMin(left , right , (pos<<1)+1); else return min(queryMin(left , mid , pos<<1) , queryMin(mid+1 , right , (pos<<1)+1)); } int main(){ while(scanf("%d%d" , &n , &q) != EOF){ for(int i = 1 ; i <= n ; i++) scanf("%d" , &height[i]); buildTree(1 , n , 1); int left , right; for(int i = 0 ; i < q ; i++){ scanf("%d%d" , &left , &right); cout<<queryMax(left , right , 1)-queryMin(left , right , 1)<<endl; } } return 0; }