来源:HDU5289
ST表+二分
代码:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
using namespace std;
int n,M;
const int MAXN = 100000+10;
int w[MAXN];
int dp1[MAXN][20];
int dp2[MAXN][20];
void ini(){
for(int i=1;i<=n;i++){
dp1[i][0]=w[i];
dp2[i][0]=w[i];
}
for(int j=1;(1<<j)<=n;j++){
for(int i=1;i+(1<<j)-1<=n;i++){
dp1[i][j]=max(dp1[i][j-1],dp1[i+(1<<(j-1))][j-1]);
dp2[i][j]=min(dp2[i][j-1],dp2[i+(1<<(j-1))][j-1]);
}
}
/*for(int j=1;(1<<j)<=n;j++){
for(int i=1;i+(1<<j)-1<=n;i++){
cout<<"max: "<<i<<" "<<i+(1<<j)<<" "<<dp1[i][j]<<endl;
cout<<"min: "<<i<<" "<<i+(1<<j)<<" "<<dp2[i][j]<<endl;
}
}*/
}
int getmax(int l,int r){
int dd=(int)((log(double(r-l+1.0)))/log(2.0));
return max(dp1[l][dd],dp1[r+1-(1<<dd)][dd]);
}
int getmin(int l,int r){
int dd=(int)((log(double(r-l+1)))/log(2.0));
return min(dp2[l][dd],dp2[r+1-(1<<dd)][dd]);
}
int get(int l,int r){
/*cout<<"in: ["<<l<<" , "<<r<<"]: "<<endl;
cout<<"max: "<<getmax(l,r)<<" min: "<<getmin(l,r)<<endl;*/
return getmax(l,r)-getmin(l,r);
}
long long ans;
void solve(){
int l,r,mid;
//cout<<"solve: "<<endl;
for(int i=1;i<=n;i++){
l=(long long)i;
r=n;
while(l+1<r){
mid=(l+r)>>1;
// cout<<l<<" "<<mid<<" "<<r<<endl;
if(get(i,mid)>=M){
r=mid;
}
else{
l=mid;
}
}
if(get(i,r)<M){
ans+=(long long)(r-i+1);
}
else{
ans+=(long long)(l-i+1);
}
}
}
int main(){
int T;
scanf("%d",&T);
while(T--){
memset(dp1,0,sizeof(dp1));
memset(dp2,0,sizeof(dp2));
scanf("%d%d",&n,&M);
for(int i=1;i<=n;i++)
scanf("%d",&w[i]);
ini();
ans=0;
solve();
printf("%lld\n",ans);
}
return 0;
}