POJ3264Balanced Lineup(线段树)
题目大意就是说给你一个长度为N的区间,并给定区间每个点的值,求Q次询问区间<x,y>之间的最大值与最小值的差
这是我第一道用线段树做的题目^_^
采用线段树记录区间x,y的最大值用最小值,每一次询问的复杂度就是logN总复杂度就是QlogN,详见代码:
1 #include <cstdio> 2 #include <cstring> 3 #include <algorithm> 4 #define MAX(a,b) (a)>(b)?(a):(b) 5 #define MIN(a,b) (a)<(b)?(a):(b) 6 #define MAXN 50010 7 using namespace std; 8 9 struct node 10 { 11 int x,y; 12 int max,min; 13 }ma[3*MAXN]; 14 int H[MAXN],N,Q; 15 16 void build_tree(int index,int x,int y)//建树,在回溯时给max与min赋值 17 { 18 ma[index].x = x; 19 ma[index].y = y; 20 if(x == y) 21 { 22 ma[index].max=ma[index].min=H[y]; 23 return; 24 } 25 int mid = (x+y)/2; 26 build_tree(index*2, x, mid);//构造左子树 27 build_tree(index*2+1, mid+1, y);//构造右子树 28 ma[index].max = MAX(ma[index*2].max, ma[index*2+1].max);//此区间的最大值就是两颗子树最大值的最大值 29 ma[index].min = MIN(ma[index*2].min, ma[index*2+1].min); 30 } 31 32 int search_max(int index,int x,int y)//找到区间最大值 33 { 34 if(ma[index].x==x && ma[index].y==y) 35 return ma[index].max; 36 int mid = (ma[index].x+ma[index].y)/2; 37 if(x > mid) //在右子树中 38 return search_max(index*2+1, x, y); 39 if(y <= mid) //在左树中 40 return search_max(index*2, x, y); 41 //在两颗子树之间 42 int L = search_max(index*2, x, mid); 43 int R = search_max(index*2+1, mid+1, y); 44 return MAX(L,R); 45 } 46 47 int search_min(int index,int x,int y)//找到区间最小值 48 { 49 if(ma[index].x==x && ma[index].y==y) 50 return ma[index].min; 51 52 int mid = (ma[index].x+ma[index].y)/2; 53 if(x > mid) 54 return search_min(index*2+1, x, y); 55 if(y <= mid) 56 return search_min(index*2, x, y); 57 int L = search_min(index*2, x, mid); 58 int R = search_min(index*2+1, mid+1, y); 59 return MIN(L,R); 60 61 } 62 63 int main() 64 { 65 while(~scanf("%d%d",&N,&Q)) 66 { 67 int i,x,y; 68 for(i = 1; i <= N; i ++ ) scanf("%d", &H[i]); 69 build_tree(1, 1, N); 70 for(i = 0; i < Q; i ++ ) 71 { 72 scanf("%d%d", &x, &y); 73 printf("%d\n", search_max(1,x,y)-search_min(1,x,y)); 74 } 75 } 76 return 0; 77 }