CDOJ 1591 An easy problem A
N个数排成一列,Q个询问,每次询问一段区间内的数的极差是多少。
Input
第一行两个整数N(1≤N≤50000),Q(1≤Q≤200000)。接下来一行N个整数a1 a2 a3 ....an,(1≤ai≤1000000000)。接下来Q行,每行两个整数L,R(1≤L≤R≤N)。
Output
对于每个询问输出一行,一个整数表示区间内的极差。
Sample input and output
Sample Input | Sample Output |
---|---|
5 3 3 2 7 9 10 1 5 2 3 3 5 |
8 5 3 |
#include <iostream> using namespace std; int N,Q,L,R,a[50010]; struct tree { int l,r,Max,Min; } tr[200010]; void build(int x,int y,int root) { tr[root].l=x; tr[root].r=y; if (x==y) { tr[root].Max=a[x]; tr[root].Min=a[x]; return; } int mid=(x+y)>>1; build(x, mid, root<<1); build(mid+1, y, (root<<1)+1); tr[root].Max=max(tr[root<<1].Max,tr[(root<<1)+1].Max); tr[root].Min=min(tr[root<<1].Min,tr[(root<<1)+1].Min); } int query_max(int x,int y,int root) { if (x==tr[root].l&&y==tr[root].r) return tr[root].Max; int mid=(tr[root].l+tr[root].r)>>1; if (x>mid) return query_max(x, y, (root<<1)+1); if (y<=mid) return query_max(x, y, root<<1); return max(query_max(x, mid, root<<1),query_max(mid+1, y, (root<<1)+1)); } int query_min(int x,int y,int root) { if (x==tr[root].l&&y==tr[root].r) return tr[root].Min; int mid=(tr[root].l+tr[root].r)>>1; if (x>mid) return query_min(x, y, (root<<1)+1); if (y<=mid) return query_min(x, y, root<<1); return min(query_min(x, mid, root<<1),query_min(mid+1, y, (root<<1)+1)); } int main() { scanf("%d%d",&N,&Q); for (int i=1; i<=N; i++) { scanf("%d",&a[i]); } build(1, N, 1); for (int i=0; i<Q; i++) { scanf("%d%d",&L,&R); printf("%d\n",query_max(L, R, 1)-query_min(L, R, 1)); } }