http://poj.org/problem?id=3264
给你一个长度为n的序列a[N] (1 ≤ N ≤ 50000),询问Q(1 ≤ Q ≤ 200000) 次,每次输出[L, R]区间最大值与最小值的差是多少。
Input
多组用例
第一行是两个整数 N,Q
然后是N个数a[i] 保证a[i] 都小于1e9
然后是Q个询问 每次给你L,R 保证(1<=L<=R<= N)
Output
输出每次询问[L, R]区间最大值与最小值的差是多少
Sample Input
6 3
1
7
3
4
2
5
1 5
4 6
2 2
Sample Output
6
3
0
区间查询最大值、最小值。线段树裸题,没啥坑点。
5月份的第50篇博客,完美AC。
//2157ms 2.4MB
#include
#include
#define inf 0x3f3f3f3f
#define lson p<<1
#define rson p<<1|1
using namespace std;
const int maxn=5e4+100;
struct node
{
int l,r;//结点所维护的区间
int mx,mn;//区间信息
}T[maxn<<2];//线段树要开四倍空间
int a[maxn];
void up(int p)
{
//区间信息的维护,将左子树所表示的区间与右子树所表示的区间合并
T[p].mx=max(T[lson].mx,T[rson].mx); //以维护最大值举例
T[p].mn=min(T[lson].mn,T[rson].mn);
}
void build(int p,int l,int r)//p表示结点编号,l、r表示结点p所表示的区间
{
T[p].l=l,T[p].r=r;//确定结点p所表示的区间[l,r]
if(l==r) //确定叶子结点所表示的信息
{
//T[p].num=a[l];
T[p].mx=T[p].mn=a[l];
return ;
}
int mid=(l+r)>>1;
build(lson,l,mid); //递归创建左子树
build(rson,mid+1,r); //递归创建右子树
up(p); //由下向上传递信息,即由两个小区间合并成一个大区间
}
int query_mx(int p,int x,int y)
{
if(x==T[p].l && y==T[p].r) //区间[x,y]恰好与结点p所表示的区间重合
return T[p].mx;//这个结点所表示的区间信息是所需要的
int mid=(T[p].l+T[p].r)>>1;
int ans=-inf;
//down(p);
if(y<=mid) //区间[x,y]一定在p的左子树上
return max(ans,query_mx(lson,x,y));
else if(x>mid) //区间[x,y]一定在p的右子树上
return max(ans,query_mx(rson,x,y));
else //没有与区间[x,y]恰好重合的结点
{
//将区间[x,y]分成两个小区间[x,mid]和[mid+1,y]
//[x,mid]一定在p的左子树上
//[mid+1,y]一定在p的右子树上
ans=max(ans,query_mx(lson,x,mid));
ans=max(ans,query_mx(rson,mid+1,y));
return ans;
}
}
int query_mn(int p,int x,int y)
{
if(x==T[p].l && y==T[p].r) //区间[x,y]恰好与结点p所表示的区间重合
return T[p].mn;//这个结点所表示的区间信息是所需要的
int mid=(T[p].l+T[p].r)>>1;
//down(p);
int ans=inf;
if(y<=mid) //区间[x,y]一定在p的左子树上
return min(ans,query_mn(lson,x,y));
else if(x>mid) //区间[x,y]一定在p的右子树上
return min(ans,query_mn(rson,x,y));
else //没有与区间[x,y]恰好重合的结点
{
//将区间[x,y]分成两个小区间[x,mid]和[mid+1,y]
//[x,mid]一定在p的左子树上
//[mid+1,y]一定在p的右子树上
ans=min(ans,query_mn(lson,x,mid));
ans=min(ans,query_mn(rson,mid+1,y));
return ans;
}
}
int main()
{
int n,m;
while(~scanf("%d%d",&n,&m))
{
for(int i=1;i<=n;i++)
scanf("%d",&a[i]);
build(1,1,n);
while(m--)
{
int x,y;
scanf("%d%d",&x,&y);
printf("%d\n",query_mx(1,x,y)-query_mn(1,x,y));
}
}
return 0;
}