看到大佬的题解都是懵的,啥是st表??马上百度看了下,发现原来是用来求区间最值的。。
下面是根据百度得到的st表讲解和大佬的题解写出来了。。。菜了
AC代码:
#include <iostream>
#include <algorithm>
#include <stdio.h>
using namespace std;
typedef long long ll;
const int N = 1e5+10;
int st_max[N][22],st_min[N][22],log2[N];
int n,m;
bool search(int l,int r,ll k){
int s = log2[r - l + 1];
int ma = max(st_max[l][s],st_max[r - (1 << s)+1][s]);
int mi = min(st_min[l][s],st_min[r - (1 << s)+1][s]);
if(ma - mi > k) return true;
else return false;
}
int main(){
scanf("%d%d",&n,&m);
for(int i = 1;i<=n;i++){
scanf("%d",&st_max[i][0]);
st_min[i][0] = st_max[i][0];
}
for(int i = 2;i<=n;i++) log2[i] = log2[i / 2] + 1; //求log
for(int j = 1;j<=21;j++){
for(int i = 1; i + (1 << j) - 1 <= n;i++){ //构造st表
st_max[i][j] = max(st_max[i][j-1],st_max[i + (1 << (j-1))][j-1]);
st_min[i][j] = min(st_min[i][j-1],st_min[i + (1 << (j-1))][j-1]);
}
}
while(m--){
int j;
ll k,ans = 0;
scanf("%d",&k);
for(int i = 1,j=1;i<=n;i++){
while(!search(i,j,k) && j<=n && i <= j){
j++;
}
if(j <= n) ans += n - j + 1;
}
printf("%lld\n",ans);
}
return 0;
}