本线段树用于求所给区间最小值。
代码:
#include<iostream>
#include<cstdio>
using namespace std;
const int inf=0x3f3f3f3f;
int minv[50]; //存储最小值
int ql,qr,p,v; //ql,qr为查询的区间两端点,修改a[p]=v。
void update(int o,int l,int r);
int query(int o,int l,int r);
int main()
{
fill(minv,minv+50,inf); //初始化
int n;
cin >> n; //输入区间长度
for(p=1;p<=n;p++) //依次输入区间的各个值
{
scanf("%d",&v);
update(1,1,n); //建树过程。
}
while(~scanf("%d%d",&ql,&qr)) //输入区间端点
{
int ans=query(1,1,n); //进行查询
cout << ans <<endl;
}
return 0;
}
int query(int o,int l,int r)
{
int m=l+(r-l)/2,ans=inf;
if(ql<=l&&r<=qr) //当前结点完全包含在查询区间内
return minv[o];
if(ql<=m) //往左走
ans=min(ans,query(o*2,l,m));
if(m<qr) //往右走
ans=min(ans,query(o*2+1,m+1,r));
return ans;
}
void update(int o,int l,int r)
{
int m=l+(r-l)/2;
if(l==r)
minv[o]=v; //叶结点,直接更新minv
else
{ //l<r
//先递归更新左子树或者右子树
if(p<=m) update(o*2,l,m); else update(o*2+1,m+1,r);
//然后计算本结点的minv
minv[o]=min(minv[o*2],minv[o*2+1]);
}
}