题目大意
查询一个区间输出最大值间最小值的差
用线段树写需要剪枝...本来明明是一道快乐的水题..却t了就用st写了..
线段树
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<queue>
#include<map>
#include<set>
#include<stack>
const int maxn=3e5+5;
using namespace std;
int n,m;
struct node{
int maxn,minn;
} tree[maxn*4];
int arr[maxn],ans1,ans2;
void built(int l,int r,int now)
{
int mid=(l+r)/2;
if(l==r)
{
tree[now]=(node){arr[l],arr[l]};
return ;
}
built(l,mid,now*2);
built(mid+1,r,now*2+1);
tree[now].maxn=max(tree[now*2].maxn,tree[now*2+1].maxn);
tree[now].minn=min(tree[now*2].minn,tree[now*2+1].minn);
}
void query(int l,int r,int left,int right,int now)
{
if(ans1>=tree[now].maxn&&ans2<=tree[now].minn) return ;//剪枝
int mid=(l+r)/2;
if(l>right) return ;
if(r<left) return ;
if(left<=l&&r<=right)
{
ans1=max(ans1,tree[now].maxn);
ans2=min(ans2,tree[now].minn);
}
if(l==r) return ;
query(l,mid,left,right,now*2);
query(mid+1,r,left,right,now*2+1);
}
int main(){
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)
{
scanf("%d",arr+i);
}
built(1,n,1);
// for(int i=1;i<=24;i++)
// {
// cout<<tree[i].maxn<<endl;
// }
for(int i=1;i<=m;i++)
{
int l,r;
scanf("%d%d",&l,&r);
ans1=0,ans2=0x7fffffff;
query(1,n,l,r,1);
//cout<<ans1<<" "<<ans2<<endl;
printf("%d
",ans1-ans2);
}
return 0;
}
st表
#include<cstdio>
#include<cmath>
#include<iostream>
using namespace std;
int a[100005],maxn[100005][35],minn[100005][35],n,m;
void f(){
int k=log(n)/log(2)+1;
for(int j=1;j<=k;j++)
{
for(int i=1;i<=n;i++)
{
if( i + (1 << j) - 1 <= n)
maxn[i][j]=max(maxn[i][j-1],maxn[i+(1<<(j-1))][j-1]);
minn[i][j]=min(minn[i][j-1],minn[i+(1<<(j-1))][j-1]);
}
}
}
int main(){
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)
{
scanf("%d",&a[i]);
maxn[i][0]=a[i];
minn[i][0]=a[i];
}
f();
while(m--)
{
int l,r;
scanf("%d%d",&l,&r);
int k=log(r-l+1)/log(2);
//cout<<k<<endl;
printf("%d
",max(maxn[l][k],maxn[r-(1<<k)+1][k])-min(minn[l][k],minn[r-(1<<k)+1][k]));
}
return 0;
}