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; }

浙公网安备 33010602011771号