解决方案一:用线段树解决,因为查询的是某区间的最值
| 时间1396 | 空间 5304 代码长度75 |
#include <iostream>
#include <algorithm>
#include <cstdio>
using namespace std;
struct node
{
int l,r,min,max;
};
const int N=100005;
int num[N];
#define L(x) (x<<1)
#define R(x) ((x<<1)+1)
#define M(x,y) ((x+y)>>1)
node tree[4*N];
int big,small;
//建立线段树,由于是某个区间并未涉及到单个点,我建立的是叶子节点区间长度为1,而不是到单个点的线段树
void build(int t,int l,int r)
{
tree[t].l=l;
tree[t].r=r;
if(l+1==r)
{
if(num[l]>num[r]){tree[t].min=num[r];tree[t].max=num[l];}
else {tree[t].min=num[l];tree[t].max=num[r];}
return;
}
int mid=M(l,r);
build(L(t),l,mid);
build(R(t),mid,r);
tree[t].max=max(tree[L(t)].max,tree[R(t)].max);
tree[t].min=min(tree[L(t)].min,tree[R(t)].min);
}
//查询操作很简单,看看这个区间的最大最小值就行了
void query(int t,int l,int r)
{
if(tree[t].l>=l && tree[t].r<=r)
{
if(tree[t].max>big)big=tree[t].max;
if(tree[t].min<small)small=tree[t].min;
return;
}
int mid=M(tree[t].l,tree[t].r);
if(r<=mid)query(L(t),l,r);
else if(l>=mid)query(R(t),l,r);
else
{
query(L(t),l,mid);
query(R(t),mid,r);
}
}
int main()
{
int i,n,q;
scanf("%d%d",&n,&q);
for(i=1;i<=n;i++)scanf("%d",num+i);
build(1,1,n);
int a,b;
while(q--)
{
scanf("%d%d",&a,&b);
big=-1,small=100000005;
//考虑问题要全面,当a==b时,线段树是不适应的,因为我建立的线段树是[a,b],[b,c],应该列出来单独考虑,在这个地方两次没提交成功
if(a==b)printf("0\n");,
else
{
query(1,a,b);
printf("%d\n",big-small);
}
}
system("pause");
return 0;
}
解决方案二:rmq的st算法即sparse table
| 时间 904 | 空间:15852 |
#include <iostream>
#include <cmath>
#include <algorithm>
#include <cstdio>
using namespace std;
const int N=100000;
int stmax[N][20],stmin[N][20],d[20];
void init(int n)
{
int i,j;
d[0]=1;
for(i=1;i<=20;i++)d[i]=d[i-1]<<1;
for(i=1;i<=n;i++){
scanf("%d",&stmax[i][0]);
stmin[i][0]=stmax[i][0];
}
int len = int(log(n*1.0)/log(2.0));
for(j=1;j<=len;j++)
for(i=1;i<=n;i++)
if(i+d[j]-1<=n)
{
stmax[i][j]=max(stmax[i][j-1],stmax[i+d[j-1]][j-1]);
stmin[i][j]=min(stmin[i][j-1],stmin[i+d[j-1]][j-1]);
}
}
void rmq(int q) //
{
int x,y,len;
while(q--)
{
scanf("%d%d",&x,&y);
len=int(log(y-x+1.0)/log(2.0));
printf("%d\n",max(stmax[x][len],stmax[y-d[len]+1][len]));
printf("%d\n",min(stmin[x][len],stmin[y-d[len]+1][len]));
}
}
int main(){
int n, q;
scanf("%d%d",&n,&q);
init(n);
rmq(q);
system("pause");
return 0;
}
|
15852 代码长度:45行 |
浙公网安备 33010602011771号