题意:给n个数字,有q个查询,每个查询给出两个数l、r,求区间[l,r]内最大值与最小值的差
解题思路:线段树.由于数据量很大,直接模拟一定会超时,所以要用线段树维护每个区间的最大值和最小值,直接套模板
代码:
#include
#include
#include
#include
#include
#include
using namespace std;
#define INF 0x3f3f3f3f
const int maxn=50000+5;
int arr[maxn];
struct SegTreeNode
{
int valx,vald;
}segTree[maxn*4];
void build(int root,int istart,int iend)
{
if(istart==iend)
{
segTree[root].valx=arr[istart];
segTree[root].vald=arr[istart];
}
else
{
int mid=(istart+iend)/2;
build(root*2,istart,mid);
build(root*2+1,mid+1,iend);
segTree[root].valx=min(segTree[root*2].valx,segTree[root*2+1].valx);
segTree[root].vald=max(segTree[root*2].vald,segTree[root*2+1].vald);
}
}
int query1(int root,int nstart,int nend,int qstart,int qend)
{
if(qstart>nend||qend=nend)return segTree[root].valx;
int mid=(nstart+nend)/2;
return min(query1(root*2,nstart,mid,qstart,qend),query1(root*2+1,mid+1,nend,qstart,qend));
}
int query2(int root,int nstart,int nend,int qstart,int qend)
{
if(qstart>nend||qend=nend)return segTree[root].vald;
int mid=(nstart+nend)/2;
return max(query2(root*2,nstart,mid,qstart,qend),query2(root*2+1,mid+1,nend,qstart,qend));
}
void updateOne(int root,int nstart,int nend,int index,int addval)
{
if(nstart==nend)
{
if(index==nstart)
{
segTree[root].valx+=addval;
segTree[root].vald+=addval;
return ;
}
}
int mid=(nstart+nend)/2;
if(index<=mid)updateOne(root*2,nstart,mid,index,addval);
else updateOne(root*2+1,mid+1,nend,index,addval);
segTree[root].valx=min(segTree[root*2].valx,segTree[root*2+1].valx);
segTree[root].vald=max(segTree[root*2].vald,segTree[root*2+1].vald);
}
int n,q;
int main()
{
while(scanf("%d%d",&n,&q)==2)
{
for(int i=1;i<=n;i++)
{
scanf("%d",&arr[i]);
}
build(1,1,n);
int l,r;
for(int i=0;i