1. 程式人生 > >POJ_3264 Balanced Lineup 【線段樹 + 區間查詢】

POJ_3264 Balanced Lineup 【線段樹 + 區間查詢】

code 選擇 bsp NPU main printf ostream 必須 pro

一、題面

POJ3264

二、分析

典型的線段樹的題,沒有更新只有查詢。

查詢的時候需要註意的是,在判斷區間是完全屬於右子樹還是左子樹時,要根據建樹的情況來選擇,不然會出錯。具體看代碼

三、AC代碼

 1 #include <cstdio>
 2 #include <cstdio>
 3 #include <iostream>
 4 #include <algorithm>
 5 #include <fstream>
 6 
 7 using namespace std;
 8 
 9 const int
MAXN = 5e4 + 15; 10 const int INF = 2e8; 11 int Data[MAXN], Max, Min; 12 struct Node 13 { 14 int l, r; 15 int nMax, nMin; 16 }segTree[MAXN<<2]; 17 18 void Build(int p, int L, int R) 19 { 20 segTree[p].l = L; 21 segTree[p].r = R; 22 if(L == R) 23 { 24 segTree[p].nMax = segTree[p].nMin = Data[R];
25 return; 26 } 27 int mid = (L + R) >> 1; 28 Build(p<<1, L, mid); 29 Build(p<<1 | 1, mid + 1, R); 30 segTree[p].nMax = max(segTree[p<<1].nMax, segTree[p<<1|1].nMax); 31 segTree[p].nMin = min(segTree[p<<1].nMin, segTree[p<<1
|1].nMin); 32 33 } 34 35 void Query(int v, int L, int R) 36 { 37 int l = segTree[v].l; 38 int r = segTree[v].r; 39 if(l == L && r == R) 40 { 41 //cout << l << " ---- " << r << " : "; 42 //cout << segTree[v].nMax << " -- " << segTree[v].nMin << endl; 43 Max = max(segTree[v].nMax, Max); 44 Min = min(segTree[v].nMin, Min); 45 return; 46 } 47 int mid = (l + r) >> 1; 48 //因為前面建樹的時候是mid+1,所以這裏必須是<不能有等於 49 if(L > mid) 50 { 51 Query(v<<1 | 1, L, R); 52 } 53 else if(R <= mid) 54 { 55 Query(v<<1, L, R); 56 } 57 else 58 { 59 Query(v<<1, L, mid); 60 Query(v<<1 | 1, mid + 1, R); 61 } 62 } 63 64 int main() 65 { 66 //freopen("input.txt", "r", stdin); 67 int N, Q; 68 while(scanf("%d %d", &N, &Q) != EOF) 69 { 70 int L, R; 71 for(int i = 1; i <= N; i++) 72 scanf("%d", &Data[i]); 73 Build(1, 1, N); 74 for(int i = 0; i < Q; i++) 75 { 76 Max = -INF, Min = INF; 77 scanf("%d %d", &L, &R); 78 Query(1, L, R); 79 printf("%d\n", Max - Min); 80 } 81 } 82 }

POJ_3264 Balanced Lineup 【線段樹 + 區間查詢】