题意要求选出 连续区间且区间内的最大最小值之差小于k 的区间个数,
用贪心,枚举左端点,从a[1]开始,接下来如果a[2]、a[3]合法,就放到set里,每次放之前与set的最大最小值比较,直到无法放入为止,然后计算当前set的size,即为a[1]为左端点所有符合条件的区间个数,然后就丢弃a【1】,以a[2]为左端点继续放元素进去set,之前计算a[1]的时候放进去set的元素,必然也对于a[2]合法、 所以总共只需要把n个元素插入,n个元素删除,set插入删除复杂度logn 总复杂度nlogn
1
#include <cstdio>
#include <cmath>
#include <cstring>
#include <string>
#include <algorithm>
#include <queue>
#include <map>
#include <set>
#include <vector>
#include <iostream>
using namespace std;
const double pi=acos(-1.0);
double eps=0.000001;
__int64 min(__int64 a,__int64 b)
{return a<b?a:b;}
__int64 max(__int64 a,__int64 b)
{return a>b?a:b;}
__int64 tm[100005];
multiset <__int64 >sb;
multiset <__int64 >::iterator it;
int main()
{
int t;cin>>t;
while(t--)
{
sb.clear();
__int64 n,k,i;
scanf("%I64d%I64d",&n,&k);
for (i=1;i<=n;i++) scanf("%I64d",&tm[i]);
__int64 st=1;
__int64 ed=1;
__int64 ans=0;
__int64 minn=tm[1];
__int64 maxx=tm[1];
sb.insert(tm[1]);
while(ed<=n)
{
if (maxx-minn<k)
{
ans+=ed-st+1;
ed++;
sb.insert(tm[ed]);
minn=*sb.begin();
it=sb.end();
if (it!=sb.begin()) it--;
maxx=*it;
}
else
{
sb.erase(sb.find(tm[st]));
st++;
minn=*sb.begin();
it=sb.end();
if (it!=sb.begin()) it--;
maxx=*it;
}
}
//ans+=n-st ;
printf("%I64d\n",ans);
}
return 0;
}