题干
hdu 5289走你
题解
#include<cstdio>
#include<cmath>
#include<algorithm>
using namespace std;
const int INF = 1e9;
const int MAX = 100010;
int root[MAX];
int mpmax[MAX*2][65];
int mpmin[MAX*2][65];
void RMQ_init(int n){
int m = log(n)/log(2);
for(int i=0;i<MAX;i++){
for(int j=0;j<65;j++){
mpmax[i][j] = -INF;
mpmin[i][j] = INF;
}
}
for(int i=1;i<=n;i++){
mpmax[i][0] = root[i];
mpmin[i][0] = root[i];
}
for(int j=1;j<=m;j++){
for(int i=1;i<=n;i++){
int pos = i + (1 << (j-1));
mpmax[i][j] = max(mpmax[i][j-1],mpmax[pos][j-1]);
mpmin[i][j] = min(mpmin[i][j-1],mpmin[pos][j-1]);
}
}
}
void query(int l, int r, int& rmax, int& rmin){
int m = log(r-l+1)/log(2) + 1;
rmax = max(mpmax[l][m-1],mpmax[r - (1<<(m-1)) + 1][m-1]);
rmin = min(mpmin[l][m-1],mpmin[r - (1<<(m-1)) + 1][m-1]);
}
int main(){
int t,n;
long long k,ans;
scanf("%d",&t);
while(t--){
scanf("%d%I64d",&n,&k);
for(int i = 1; i <= n; i++)scanf("%d",&root[i]);
RMQ_init(n);
ans = 0;
for(int i = 1; i<= n; i++){
int l = i,
r = n,
mid = r,
max, min, kk;
while(l <= mid && mid <= r){
query(l, mid, max, min);
kk = max - min;
if(kk>=k){
r = mid - 1;
mid = (l + r) / 2;
}else{
if(mid == r)break;
mid = (mid + r) / 2 + (mid + r) % 2;
}
}
ans = ans + r - i + 1;
}
printf("%I64d\n",ans);
}
return 0;
}