1. 程式人生 > 其它 >A - Balanced Lineup

A - Balanced Lineup

題目:

題目網址: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; }