题目大意:
给出N个数,M个询问,每次询问一个区间[Li,Ri]的最大值。
题解:
一道求区间最值的题,
由于支持离线,所以我们可以用ST算法去做
并不是很会打ST,所以顺带着学了一波,
发现挺简单的,
我们能够设f[i][j]表示区间[i-2^j+1,i]的最大值
则可以推得转移:
f[i][j]=min(f[i-2^(j-1)][j-1],f[i][j-1])
即前后半段的最大值的最大值
我们预处理一下log(i)和2^i次方的值即可
代码:
#include<bits/stdc++.h>
#define N 100005
using namespace std;
int n,m,a[N],cnt[N],f[N][20],num[20];
int main()
{
num[0]=1;
for (int i=1; i<=20; i++) num[i]=num[i-1]*2;
scanf("%d%d",&n,&m);
cnt[1]=0;
for (int i=2; i<=n; i++) cnt[i]=cnt[i/2]+1;
for (int i=1; i<=n; i++) scanf("%d",&a[i]);
for (int i=1; i<=n; i++)
{
f[i][0]=a[i];
for (int j=1; j<=cnt[i]; j++)
f[i][j]=max(f[i][j-1],f[i-num[j-1]][j-1]);
}
int l,r;
for (int i=1; i<=m; i++)
{
scanf("%d%d",&l,&r);
int len=cnt[r-l+1];
int ans=max(f[l+num[len]-1][len],f[r][len]);
printf("%d\n",ans);
}
return 0;
}