求任意区间满足R-L< K 的数量
#include <stdio.h>
#include <string.h>
#include <iostream>
#include <algorithm>
#include <queue>
#include <cmath>
using namespace std;
typedef long long LL;
const int inf = 0x3f3f3f3f;
const double oo = 10e9;
const double eps = 10e-9;
const int MAXN = 100010;
//int dp[MAXN][20];
int maxsum[MAXN][20],minsum[MAXN][20];
int mm[MAXN],a[MAXN];
void intRMQ(int n,int b[])
{
mm[0]=-1;
for(int i=1; i<=n; ++i)
{
mm[i]=((i&(i-1))==0)?mm[i-1]+1:mm[i-1];
//dp[i][0]=b[i];
maxsum[i][0]=minsum[i][0]=b[i];
}
for(int j=1; j<=mm[n]; ++j) //for(int j=1;(1<<j)<=n;++j)
for(int i=1; i+(1<<j)-1<=n; ++i)
{
//dp[i][j]=max(dp[i][j-1],dp[i+(1<<(j-1))][j-1]);
maxsum[i][j] = max(maxsum[i][j - 1], maxsum[i + (1 << (j - 1))][j - 1]);
minsum[i][j] = min(minsum[i][j - 1], minsum[i + (1 << (j - 1))][j - 1]);
}
}
int rmq(int x,int y)
{
int k=mm[y-x+1];
return max(maxsum[x][k],maxsum[y-(1<<k)+1][k]);
}
int rmq2(int x,int y)
{
int k=mm[y-x+1];
return min(minsum[x][k],minsum[y-(1<<k)+1][k]);
}
int main()
{
int n,k;
int t;
scanf("%d",&t);
while(t--)
{
scanf("%d%d",&n,&k);
for(int i=1; i<=n; ++i)
{
scanf("%d",&a[i]);
}
intRMQ(n,a);
LL ans=0;
int q=1;
int l,r;
for(int i=1; i<=n; ++i)
{
l=q;
r=i;
while(l<=r)
{
int mid=(l+r)/2;
int high=rmq(mid,i);
int low=rmq2(mid,i);
int tmp=high-low;
if(tmp>=k)
{
l=mid+1; //收缩查询空间
//左边向右缩小
}
else if(tmp<k) //扩大查询空间
r=mid-1;
}
q=l;
ans+=i-l+1;
}
printf("%I64d\n",ans);
}
return 0;
}