Balanced Lineup POJ - 3264

For the daily milking, Farmer John's N cows (1 ≤ N ≤ 50,000) always line up in the same order. One day Farmer John decides to organize a game of Ultimate Frisbee with some of the cows. To keep things simple, he will take a contiguous range of cows from the milking lineup to play the game. However, for all the cows to have fun they should not differ too much in height.

Farmer John has made a list of Q (1 ≤ Q ≤ 200,000) potential groups of cows and their heights (1 ≤ height ≤ 1,000,000). For each group, he wants your help to determine the difference in height between the shortest and the tallest cow in the group.

Input

Line 1: Two space-separated integers,  N and  Q
Lines 2..  N+1: Line  i+1 contains a single integer that is the height of cow  i 
Lines  N+2..  NQ+1: Two integers  A and  B (1 ≤  A≤  B ≤  N), representing the range of cows from  Ato  B inclusive.

Output

Lines 1..  Q: Each line contains a single integer that is a response to a reply and indicates the difference in height between the tallest and shortest cow in the range.

Sample Input

6 3
1
7
3
4
2
5
1 5
4 6
2 2

Sample Output

6
3
0

题意:给你长度不超过50000的数组,然后问你在指定区域内最大值于最小值的差是多少。

思路:由于要求区间类的操作,首先是线段树,而这个题就比较简单了,首先在线段树初始化时给每个节点设置两个值,分别是这个节点的最大值和最小值
。由于数据又不是很大,因此可以写两个区间求值方法,一个求最大值,一个求最小值,在相减一下就行了。

代码:
  1 #include <cstdio>
  2 #include <fstream>
  3 #include <algorithm>
  4 #include <cmath>
  5 #include <deque>
  6 #include <vector>
  7 #include <queue>
  8 #include <string>
  9 #include <cstring>
 10 #include <map>
 11 #include <stack>
 12 #include <set>
 13 #include <sstream>
 14 #include <iostream>
 15 #define mod 998244353
 16 #define eps 1e-6
 17 #define ll long long
 18 #define INF 0x3f3f3f3f
 19 using namespace std;
 20 
 21 struct node
 22 {
 23     //l表示左边,r表示右边
 24     int l,r,mi,ma;
 25 
 26 };
 27 node no[500000];
 28 int num[50000];
 29 
 30 //初始化
 31 //k表示当前节点的编号,l表示当前区间的左边界,r表示当前区间的右边界
 32 void build(int k,int l,int r)
 33 {
 34     no[k].l=l;
 35     no[k].r=r;
 36     //如果递归到最低点
 37     if(l==r)
 38     {
 39         no[k].mi=num[l];
 40         no[k].ma=num[l];
 41         return ;
 42     }
 43     //对半分
 44     int mid=(l+r)/2;
 45     //递归到左线段
 46     build(k*2,l,mid);
 47     //递归到右线段
 48     build(k*2+1,mid+1,r);
 49     //更新当前节点的值
 50     no[k].mi=min(no[k*2].mi,no[k*2+1].mi);
 51     no[k].ma=max(no[k*2].ma,no[k*2+1].ma);
 52 }
 53 //求区间内最小值
 54 int querymi(int k,int l,int r)
 55 {
 56     //到对应层时返回值
 57     if(no[k].l==l&&no[k].r==r)
 58     {
 59         return no[k].mi;
 60     }
 61     //取中值
 62     int mid=(no[k].l+no[k].r)/2;
 63     if(r<=mid)
 64     {
 65         return querymi(k*2,l,r);
 66     }
 67     else if(l>mid)
 68     {
 69         return querymi(k*2+1,l,r);
 70     }
 71     else
 72     {
 73         return min(querymi(k*2,l,mid),querymi(k*2+1,mid+1,r));
 74     }
 75 }
 76 //求区间内最大值
 77 int queryma(int k,int l,int r)
 78 {
 79     //到对应层时返回值
 80     if(no[k].l==l&&no[k].r==r)
 81     {
 82         return no[k].ma;
 83     }
 84     //取中值
 85     int mid=(no[k].l+no[k].r)/2;
 86     if(r<=mid)
 87     {
 88         return queryma(k*2,l,r);
 89     }
 90     else if(l>mid)
 91     {
 92         return queryma(k*2+1,l,r);
 93     }
 94     else
 95     {
 96         return max(queryma(k*2,l,mid),queryma(k*2+1,mid+1,r));
 97     }
 98 }
 99 int main()
100 {
101     int q,n;
102     scanf("%d %d",&n,&q);
103     for(int i=1;i<=n;i++)
104     {
105         scanf("%d",&num[i]);
106     }
107     build(1,1,n);
108     int a,b;
109     for(int i=0;i<q;i++)
110     {
111         scanf("%d %d",&a,&b);
112         printf("%d\n",queryma(1,a,b)-querymi(1,a,b));
113     }
114 }


猜你喜欢

转载自www.cnblogs.com/mzchuan/p/11808288.html