A - Balanced Lineup
阿新 • • 發佈:2021-08-04
題目:
題目網址:3264 -- Balanced Lineup (poj.org)
思路:
用線段樹來儲存區間內的最大最最小值差異;
程式碼實現:
#include <iostream> #include <stdio.h> #include <algorithm> #include <string.h> #include <math.h> using namespace std; int t,n,q; long tree1[50010<<2]; long tree2[50010<<2]; long a[50010];void PushUp(int rt){ tree1[rt] =max(tree1[rt*2] , tree1[rt*2+1]) ; ///區間和的更新操作 tree2[rt] =min(tree2[rt*2] , tree2[rt*2+1]) ; } void Build(int l,int r,int rt){ // l,r 代表的是這個區間內的左端點和右端點,rt代表的是 [l,r] 這個區間內的值是存在哪一個位置的。 if(l==r){ //scanf("%d",&tree[rt]); tree1[rt] = a[l]; tree2[rt]= a[l]; return; } int m=(l+r)/2;// 對於區間區分,我們一般將m點劃入左半邊區間 Build(l,m,rt*2); Build(m+1,r,rt*2+1); PushUp(rt); // PushUp 函式是通過2個子節點來更新現在這個節點的狀態, 對於不同的要求需要不同的寫法。 } long MAXQuery(int l,int r,int rt,int L,int R){// [L,R]為查詢區間 if(L <= l && r <= R){ return tree1[rt];//如果成立則滿足查詢區間覆蓋了當前區間, 直接返回當前區間的值 } int m=(l+r)/2; long res=0; if(L<=m) res=max(res,MAXQuery(l,m,rt*2,L,R));//左邊有一部分需要查詢的區域。 if(m<R) res=max(res,MAXQuery(m+1,r,rt*2+1,L,R));//右邊有一部分。 return res; } long MINQuery(int l,int r,int rt,int L,int R){// [L,R]為查詢區間 if(L <= l && r <= R){ return tree2[rt];// 如果成立則滿足查詢區間覆蓋了當前區間, 直接返回當前區間的值 } int m=(l+r)/2; long res=0x3f3f3f; if(L<=m)
res=min(res,MINQuery(l,m,rt*2,L,R));//左邊有一部分需要查詢的區域。 if(m<R)
res=min(res,MINQuery(m+1,r,rt*2+1,L,R));//右邊有一部分。 return res; } int main() { scanf("%d%d",&n,&q); for(int i = 1; i <= n; i++) scanf("%ld", &a[i]); Build(1,n,1); int a,b; while(q--){ scanf("%d%d",&a,&b); cout << MAXQuery(1,n,1,a,b)-MINQuery(1,n,1,a,b) << endl; } return 0; }