效率至上
題意:
題意很簡單,給出一個數目爲n的非有序序列,然後有m次查詢.對於每次查詢輸入兩個正整數l,r請輸出區間[l,r]的最大值與最小值的差值
輸入:
第一行:輸入兩個正整數n,m (1<=n<=50000, 1<=m<=200000 );
第二行:輸入n個整數 大小範圍爲[1,100000];
接下來的m行,每次兩個正整數l,r (1<=l<=r<=n);
輸出:
輸出區間[l,r]最大值與最小值的差值.
思路:
套用線段樹模板,在線段樹結構體里加兩個值,分別記錄當前區間內的最小值和最大值,然後只需要每次選出區間內的最大值和最小值,將他們做減法輸出即可。
代碼
#include<iostream>
#include<cstdio>
using namespace std;
struct node
{
long long l,r,v,ma,mi;
} tree[400000];
long long x,y,MAX,MIN;
int maxn(int a,int b)
{
return a>b?a:b;
}
int minn(int a,int b)
{
return a<b?a:b;
}
void build(long long i,long long l,long long r)
{
tree[i].l=l;
tree[i].r=r;
tree[i].v=0;
tree[i].mi=0x3f3f3f;
if(l==r)
{
scanf("%lld",&tree[i].v);
tree[i].mi=tree[i].ma=tree[i].v;
return ;
}
long long mid=(l+r)/2;
build(i*2,l,mid);
build(i*2+1,mid+1,r);
tree[i].v=tree[i*2+1].v+tree[i*2].v;
tree[i].ma=maxn(tree[i*2+1].ma,tree[i*2].ma);
tree[i].mi=minn(tree[i*2+1].mi,tree[i*2].mi);
}
void maxx(long long i)
{
if(tree[i].l>=x&&tree[i].r<=y)
{
MAX=maxn(MAX,tree[i].ma);
return ;
}
long long mid=(tree[i].l+tree[i].r)/2;
if(x<=mid)
{
maxx(i*2);
}
if(y>mid)
{
maxx(i*2+1);
}
}
void minx(long long i)
{
if(tree[i].l>=x&&tree[i].r<=y)
{
MIN=minn(MIN,tree[i].mi);
return ;
}
long long mid=(tree[i].l+tree[i].r)/2;
if(x<=mid)
{
minx(i*2);
}
if(y>mid)
{
minx(i*2+1);
}
}
int main()
{
int n,m,i;
cin>>n>>m;
build(1,1,n);
while(m--)
{
MAX=-1;
MIN=0x3f3f3f;
scanf("%lld%lld",&x,&y);
maxx(1);
minx(1);
printf("%d\n",MAX-MIN);
}
return 0;
}